オンプレミス版app-searchをDockerで動作確認する

概要

Elastic App Searchというものをご存じでしょうか。 Elasticsearchで全文検索をやろうと思うと、データの中身や、させたい検索を考慮して、インデックスやマッピングの設計が必要になりますが、 そうしたものをマルっと意識せずに、データの出し入れに注力できるような製品です。(だと思います)

www.elastic.co

During the beta period, you can spin Elastic App Search up on your own hardware at no charge. To do so, download App Search.

ベータの間は、no charge で試せるということです。 正月早々人柱になるのも一興です。というわけで、やってみるんですが、今回はDockerでやったときの内容と、諸注意をまとめておきたいと思います。

次回予告用

app-searchは、様々な言語にあわせた設定をもっており、「日本語」があります。

f:id:tsgkdt:20190104221432p:plain
jap

検索大好きっ子の中では、日本語の検索をするときにどういう設定を思い浮かべるでしょうか。

  • 精度をとるか、漏れをなくすか?
  • 形態素?
  • n-gram? (nはいくつにする?)
  • 形態素、ngram併用型ならランクの重みづけは?
  • StopwardsやStoptagsは?
  • 読みも含めるならICUも?

など、いろいろ思いつく設定があろうかと思います。 app-searchで日本語を指定したら、どんな設定になるのだろう? Elastic社にジョインしたSwiftypeの考える日本語設定でどんなのさ? と気になりませんか? このあたりを次回ご紹介したいと思います。(という予定)

f:id:tsgkdt:20190104222354p:plain
osuman

Dockerイメージの作成

まずは、app-search用のDockerイメージを作成しましょう。

バイナリの入手元

以下から、app saerchのバイナリを入手することができます。 現状では、Mac or Linuxでのみ動作し、Windowsでは動きません。

www.elastic.co

解凍して、bin/app-searchを実行するだけ、とあります。

Dockerfileの作成

このような感じでイメージを作成しています。

FROM openjdk:8-jdk

ENV APP_SEARCH_VERSION=0.1.0-beta1
ENV APP_SEARCH_FILE=appsearch-${APP_SEARCH_VERSION}.tar.gz
ENV APP_SEARCH_DIR=/usr/share/app-search
ENV APP_SEARCH_USER=appsearch

RUN curl -s -O https://appsearch.elastic.co/downloads/appsearch/${APP_SEARCH_FILE} && \
    tar xvf ${APP_SEARCH_FILE} && \
    mv appsearch-${APP_SEARCH_VERSION} ${APP_SEARCH_DIR} && \
    sed -i -e 's/Dwarbler.host=$APP_SEARCH_HOST/Dwarbler.host=0.0.0.0/g' /usr/share/app-search/lib/entrypoints/app-server.sh && \
    useradd ${APP_SEARCH_USER} && \
    ls -al ${APP_SEARCH_DIR}/bin && \
    chmod +x ${APP_SEARCH_DIR}/bin/app-search && \
    chown -R ${APP_SEARCH_USER} ${APP_SEARCH_DIR}/

USER ${APP_SEARCH_USER}
WORKDIR ${APP_SEARCH_DIR}

EXPOSE 3002

CMD ["bin/app-search"]

デフォルトでは、APP_SEARCH_HOST環境変数で指定された値で待ち受ける内容となっているようですが、 0.0.0.0で待っておきたかったので、書き換えています。

今回は、これを app-search:latestとしてイメージをビルドしたとして、話を先に進めます。

注意点

app-search用ポート

jettyの都合で、rootでなければポート80で待ち受け出来ません。パーミッションのエラーになってしまいます。 なので、rootでないユーザで起動する場合は、APP_SEARCH_PORTを80にするのではなく、デフォルトの3002にするとか、8080にするのが良いです。

app-search用ホストとポート

APP_SEARCH_HOST, APP_SEARCH_PORTで指定する値は、Previewや画面リソースのダウンロードする際のURLの埋め込みに使用されます。 Preview画面で検索がうまく動かないときは、この値がローカルアドレスを指しているとか、接続できる状態になっているかを確認してみてください。

たとえば、コンテナ起動時のポートマッピングで、80:8080のような環境になっていると、 内部的に埋め込まれたリソースは http://xxx.xxx.xxx.xxx:8080/ のようになってしまうため、 アクセスすることができないです。 この現象に遭遇するのは、Preview画面です。

Elasticsearch接続情報

app-searchからElasticsearchへの接続情報は、環境変数で渡すことができます。

X-PackのSecurityを入れていない、特にユーザ名、パスワードが不要な環境の場合は、”” で空文字を指定しておきます。

起動

docker-compose

version: '2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.5.4
    container_name: elasticsearch
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  kibana:
    image: docker.elastic.co/kibana/kibana:6.5.4
    container_name: kibana
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch
    links:
      - elasticsearch:elasticsearch
    networks:
      - esnet
  app-search:
    image: app-search:latest
    container_name: app-search
    environment:
      - ALLOW_ES_SETTINGS_MODIFICATION=true
      - ELASTICSEARCH_HOST=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=""
      - ELASTICSEARCH_PASSWORD=""
      - APP_SEARCH_HOST=XXX.XXX.XXX.XXX
      - APP_SEARCH_PORT=8080  
    ports:
      - 8080:8080
    depends_on:
      - elasticsearch
    links:
      - elasticsearch:elasticsearch
    networks:
      - esnet

volumes:
  esdata:
    driver: local

networks:
  esnet:

起動確認

docker logs でログを確認すると、Startedと出ている部分があります。これが出ていれば起動完了です。

f:id:tsgkdt:20190104220504p:plain
server has started

起動途中には、赤字でWARNINGが出ますが、jettyの起動を焦らず待ちましょう。

f:id:tsgkdt:20190105002056p:plain
beta

ログイン画面

http://xxx.xxx.xxx.xxx:8080/ にアクセスすると、このようなログイン画面を見ることができます。

f:id:tsgkdt:20190105001557p:plain
login

  • ID : app-search@example.com
  • PASS: changeme (デフォルト)

チュートリアル画面

初回ログイン時には、チュートリアル画面が出ます。

Create your first Engine

ここで、Engineを作成することで、Elasticsearchのインデックスが作られる、というわけですな。 名前と、言語の欄を指定して次に進めます。

f:id:tsgkdt:20190105002209p:plain
tutorial

Index Data

データ登録画面です。 テキストをjsonとして貼り付けるか、ファイルアップロードを選択することができます。

f:id:tsgkdt:20190105002350p:plain
data

テキストの貼り付けでは、初期値としてテストデータが2件分入っており、そのままContniueすればデータがすんなり登録できます。

f:id:tsgkdt:20190105002512p:plain
paste

Explorer the Dashboard

f:id:tsgkdt:20190105002828p:plain
dashboard

Dashbaord

画面からシノニムやRelevanceのTuningができることがうかがえます。

f:id:tsgkdt:20190105003437p:plain
dashboard

Reference UI

データの管理が簡単なのは分かりました。検索画面はどうすんのさ、自分でReactの画面とか書きたくないっす、という方もいらっしゃるかと思います。 そういう方の強い味方、画面でパチパチするだけで検索画面が生成出来ちゃうんです。

f:id:tsgkdt:20190105003941p:plain
reference UI

column 説明 設定例
Title field Used as the top-level visual identifier for every rendered result title
Filter fields Faceted values rendered as filters and available as query refinement title
Sort fields Used to display result sorting options, ascending and descending id
URL field (Optional) Used as a result's link target, if applicable url

テストデータの場合は、設定例のような値を指定してやると良いでしょう。 埋めて、Generate Previewボタンを押してみてください。

すると、こんな画面が表示されます。

f:id:tsgkdt:20190105004824p:plain
preview

この画面でも検索したり、動作を確認することができます。 thisで検索すると、body部にてヒットした部分がハイライトされていることが分かります。 画面右上「Download ZIP Package」から画面リソースのダウンロードができます。

ダウンロードしたzipファイルの中身はこのようになっていました。

f:id:tsgkdt:20190105005025p:plain
zip contents

ベースができたので、あとは、この中身を少し手入れしてどこかのサーバでホストしてやれば良いということになりますね。 デプロイのイメージとしては、以下のようになるかと思います。

f:id:tsgkdt:20190105010221p:plain
deploy

パスワード変更

デフォルトのパスワードのままはよろしくありません。 なるはや変えたいところです。パスワードを変更するには左メニュー「ACCOUNT」の「Settings」から変更することができます。 (パスワード自体は暗号化された状態で、Elasticsearchのapp-searchが管理するインデックス内に格納されています。)

f:id:tsgkdt:20190105003031p:plain
passwd

まとめ

Elasticsearchの検索UIコンポーネントというと、ReactだとReactivesearchなるものがあるそうです。

qiita.com

今回紹介しているApp SearchのReference UIでは、Reactivesearchではなく、ElasticファミリーのSwiftypeが頑張ってコンポーネントを作っているように見受けられます。

app-search-reference-ui-react/src/components at master · swiftype/app-search-reference-ui-react · GitHub

App Search自体は、API KEYを渡してクエリを投げれば結果が返ってくる、という使い方がベースにあるので、画面がReactivesearchだろうが、curlだろうが何でも良いんでしょうけれど、 シノニムやブーストに加えて、Reference UIが標準で備わっている、というところは製品としてまとまってるな、と感じさせるところだと思いました。

欲をいえば、データの投入部分、ファイルサーバなんかをクロールして(差分管理もしつつ)取り込む部分も標準でツールとして提供してくれるようになると、 カオスなファイルサーバを抱えた人たちに、支持されそうなな気がします。

ではでは。