Skip to content

Elasticsearch の nested 型のハイライト

Elasticsearch の nested 型のハイライト published on Elasticsearch の nested 型のハイライト へのコメントはまだありません

本投稿は、一つ前の「Elasticsearch多言語化その2」の補足。

ゴール

やりたい事は、以下のようなフィールドに対する検索結果のハイライトをすること。

  • nested 型で、中身は複数の “attachment” 型
  • attachment 型の “content” フィールドには、content.{ja,en,…} というサブフィールドを作成し、各言語毎の analyzer で処理する

マッピング定義は以下の通り。(elastic4s の DSL をそのままコピペしたが、まぁ大体理解してもらえるかと。)

val messageMapping = mapping("message").fields(
  "title_v3" typed StringType fields(
    "en" typed StringType analyzer "english",
    "ja" typed StringType analyzer "ja_kuromoji_neologd",
  ),
  "body_v3" typed StringType fields(
    "en" typed StringType analyzer "english",
    "ja" typed StringType analyzer "ja_kuromoji_neologd",
  ),
  "attached_files_v3" nested (
    "attached_file" typed AttachmentType fields (
      "content" typed StringType fields(
        "en" typed StringType analyzer "english" termVector ("with_positions_offsets") store (true),
        "ja" typed StringType analyzer "ja_kuromoji_neologd" termVector ("with_positions_offsets") store (true),
      )
    )
  ) includeInRoot (true)
)

環境は以下の通り

  • Elasticsearch 2.3.5
  • Elasticsearch Mapper Attachments プラグインを使用
  • elastic4s というライブラリ経由で Scala から使用

TL; DR

先に結論を書いておくと、以下の2つがうまくいった。

  • nested 型のフィールドに include_in_root を指定し、検索時には通常のクエリーを実行
  • 通常の nested 型のフィールドに対し、nested query を実行し、inner hits でハイライト対象フィールドを指定

どちらの場合も、 “term_vector”: “with_positions_offsets” と “store”: “true” は、attached_file.content.{ja,en} につける。

上手く行かなかったのは以下の方法。

  • nested query を実行し、highlight query でも nested query を実行

以下、詳細に説明していく。

Continue reading Elasticsearch の nested 型のハイライト

国際化

Elasticsearch多言語化その2

Elasticsearch多言語化その2 published on Elasticsearch多言語化その2 への2件のコメント

本投稿は、Elastic stack (Elasticsearch) Advent Calendar 2016 の2日目の記事かつ、以前書いた以下の投稿の続編。

背景等

以前書いた内容と重なる部分もあるが、背景等について説明しておく。

Elasticsearch を、各種開発者向けサービスの横串検索用に使用

GitHub, Slack, Google Drive 等のデータを API 経由で取ってきて、Elasticsearch に入れて、それを横串・一括検索出来るようなツールを作っている。元々は内部向けのツールだったが、ぼちぼち体裁等が整って来たので、現在β版的な感じでひっそり公開中。(今年中にはちゃんと公開したい。)

詳細はこちら → GitHub も、Slack も、まとめて検索 | Commet

検索対象の特性は、メイン言語+英語 or 英語のみ

開発チームまたはプロジェクトが1つの大きな単位で、そのチーム・プロジェクトで使っている GitHub のレポジトリ、Slack のチャンネル、Google Drive のフォルダを指定すると、その配下のデータが Commet 上に取り込まれる。

私の(そして、想定しているターゲット)のユースケースとしては、オフショアを利用していたり、メンバーが多国籍だったりする場合もあるが、使われている言語は、基本的には以下のどちらか。

  • メインとして使われている言語(日本語等)+英語
  • 英語オンリー

環境

  • Elasticsearch 2.3.5
  • elastic4s というライブラリ経由で Scala から使用

Continue reading Elasticsearch多言語化その2

stop-arret

Elasticsearch多言語化その1

Elasticsearch多言語化その1 published on Elasticsearch多言語化その1 へのコメントはまだありません

英語でもそこそこの検索結果が出て欲しい

以前、Elasticsearch の analyzer 関連の投稿を書いた。

Elasticsearch の analyzer 関連の設定で知ってることを全て書く

Elasticsearch を何に使っているかなどは、詳しくはそちらを参照してもらうとして、ポイントだけ抜粋しておく。

  • GitHub, Slack, Google Drive, ChatWork, Backlog などからAPI経由でデータを取ってきて、インデックスを作成
  • 言語は、日本語がメインだけど、海外の人とのやりとりや、英語のwebページ(StackOverflowとか)からのコピペもあるので、英語もある程度使われている。

現状は、日本語にのみ対応した設定だけど、英語もそこそこ使われているので、英語の検索結果もそれなりの精度になって欲しい、というのが今回の話。

やったこと: 英語の stemmer を filter として追加

先に結論を書いておくと、使用している analyzer に、”english” と “possessive_english” という2つの stemmer を filter のところに追加した。

設定方法などは、詳しくは以下のページを参照。

Stemmer Token Filter | Elasticsearch Reference [5.0] | Elastic

Continue reading Elasticsearch多言語化その1

Elasticsearch の analyzer 関連の設定で知ってることを全て書く

Elasticsearch の analyzer 関連の設定で知ってることを全て書く published on Elasticsearch の analyzer 関連の設定で知ってることを全て書く へのコメントはまだありません

詳しい人から見れば大した内容じゃないと思うけど、調べたり試行錯誤した結果をまとめる。(間違いなどがあれば、ご指摘頂けるとありがたいです。)

Elasticsearch を何に使っているか

他サービス → API/webhook → 自サーバーの Elasticsearch

以前触れたと思うけど、開発プロジェクトのデータを全部1箇所にまとめて検索出来るようにしていて、そこで Elasticsearch を使っている。

自分の仕事内容としては、時間の4割位を受託開発にあてている。受託開発では、お客様や発注元の開発ベンダーに合わせて色んなツールを使わざるを得なくて、具体的には ChatWork, Backlog, Google Drive とかを使うことが結構多い。それに対して、自分達の開発チーム内部では自分達用のSlackチームがあるし、それ以外にも別のツールを使ってたりしているので、色んなところに情報が分散しがち。

なので、各ツールのAPI(あるいはwebhook)経由で自分達のサーバーにデータを送って、それを Elasticsearch に流し込んでいる。

検索対象

元データの種類は以下の通り。

  • テキスト
    • GitHub/Bitbucket/Backlog の issue (チケット), PR での議論
    • Slack, ChatWork の会話
    • wiki ページ
  • ファイル
    • Backlog のファイル置き場にあるファイル
    • Google Drive のファイル
    • Slack に貼られたファイル

言語は、日本語がメインだけど、海外の人とのやりとりや、英語のwebページ(StackOverflowとか)からのコピペもあるので、英語もある程度使われている。

Continue reading Elasticsearch の analyzer 関連の設定で知ってることを全て書く

Elasticsearch で SQL の update みたいな事をする

Elasticsearch で SQL の update みたいな事をする published on Elasticsearch で SQL の update みたいな事をする へのコメントはまだありません

SQL の update みたいなことがしたい

Elasticsearch (以下ES) は RDB じゃないってのは理解しつつも、場合によっては SQL での update 文みたいな事がしたい。

現状だと、scan & scroll → Update API でドキュメントを1つ1つ更新する、みたいな事しかできない。

PRがあるがマージされていない

同じことを考えている人は多いみたいで、ググると、ちょくちょくESの issue tracker に同じような内容で登録されている(これとか)。で、PRとかも投げられてるけど、

「”update” 処理は長時間かかる場合も多いけど、途中で止める仕組みがないので」

みたいな理由でマージされていない。

Continue reading Elasticsearch で SQL の update みたいな事をする

elastic4s でエラー処理

elastic4s でエラー処理 published on elastic4s でエラー処理 へのコメントはまだありません

Scala から Elasticsearch を操作するクライアントライブラリ

Elasticsearch のサイトには、以下の4つが紹介されている

更新具合その他を考えて、elastic4sを使うことにした。

Elastic4s の使い方 → RTFM

基本的な使い方は以下を参照。

エラー処理

ドキュメントだと、エラーが起きた時にどう処理をすれば良いかが書いていない。

例えば、documentを追加するコードは

esClient.execute {
   index into s"index1/type1" fields ("field1" -> "val")
}

みたいに書くけど、エラーが起きたらどうするんだろうと思った。

上の式のシグニチャーをみると Future[IndexResponse] らしい。IndexResponse は Elasticsearch の API で提供されている。ドキュメントはこの辺

ドキュメントに追加できなかった場合は、isCreated メソッドが false を返す。それ以外に、サーバー側でエラーが起きたりとかした場合には例外が投げられる。

ということで、例えば以下のように処理できる。

import com.sksamuel.elastic4s.ElasticDsl._
import org.elasticsearch.action.index.IndexResponse
import org.elasticsearch.transport.RemoteTransportException

val f: Future[Boolean] = esClient.execute {
   index into s"index1/type1" fields ("field1" -> "val")
} map (_.isCreated) recover {
  case e: RemoteTransportException =>
    Logger.error(e.getMessage)
    false
}

この辺はニーズに応じて好きなようにすれば良いかなと。

その他

コードをみたけど、結構ちゃんと書かれていた(と個人的には思った)。

まとめ?

Elasticsearch 便利。elastic4s も便利。

Elasticsearchでmappingを更新して日本語対応する

Elasticsearchでmappingを更新して日本語対応する published on Elasticsearchでmappingを更新して日本語対応する へのコメントはまだありません

今作っているシステムで、全文検索部分にElasticsearchを採用した。理由は、使ったことなかったので触ってみたかったから。

環境はElasticsearch 1.4

インストールとか

ドキュメント見ればいいので、省略。RedHat系の場合もUbuntuの場合も、パッケージを使えばいいと思う。

データを入れてみる

「へー。スキーマとか定義しなくても、勝手にデータ型とか定義してくれるんだ。でも日本語はどうするんだろう?まぁ後で変更すればいっか。」

この辺を読んで思った。

データの投入の仕方はcurlを使う場合はこんな感じ。ちなみに、そのページの最初にも書いてあるけど、以下の用語については最初に覚えておかないとドキュメントを読むときに困る。

  • Index -> RDBにおけるdatabase
  • Type -> RDBにおけるtable
  • Document -> RDBにおけるrow
  • Field -> RDBにおけるcolumn

データを投入すると、勝手にfieldとかが定義される。

Continue reading Elasticsearchでmappingを更新して日本語対応する