検索文字からドキュメントの完全一致をしたい

専門用語の辞書を作成しています。

以下のようなドキュメントが入っています。

  1. 赤パジャマ
  2. 青パジャマ
  3. 黄パジャマ

この文字を以下で検索します。

  • 僕は黄パジャマを着たい。貴方は赤パジャマにしたら?

文字列が以下のように形態素解析されるとして、

僕 は 黄 パジャマ を 着たい。 貴方 は 赤 パジャマ に したら?

その結果以下が欲しいです。

  • 青パジャマ
  • 赤パジャマ

試した方法と考えた解決案

1. ドキュメントを解析(デフォルト)

  • ドキュメント
赤パジャマ → 赤、パジャマ → 赤(0:0)、パジャマ(0:1)
青パジャマ → 青、パジャマ → 青(1:0)、パジャマ(1:1)
黄パジャマ → 黄、パジャマ → 黄(2:0)、パジャマ(2:1)
  • インデックス
赤 0:0
青 1:0
黄 2:0
パジャマ 0:1, 1:1, 2:1
  • 検索
赤 0:0
黄 2:0
パジャマ 0:1, 1:1, 2:1

→ 0, 1, 2全部ヒットする

2. ドキュメントをnot_analyzed

検索する文字列が不適切に分割された場合にヒットしない
赤、パジャマと分割されているのでヒットしない

解決案

解析済みのテキストにはポジションがあるので以下のようにできないか考えています。
1でインデックスを検索した結果以下のように想定できます。

赤 0:0
黄 2:0
パジャマ 0:1, 1:1, 2:1

その結果、全てがヒットしますが、ドキュメントに着目すると

0:0, 0:1 → 赤パジャマ
1:1 → パジャマ
2:0, 2:1 → 黄パジャマ

となり、1:0が無いので青パジャマを除外できるのじゃないかと考えました。

検索クエリでこのpositionやドキュメントIDの演算ができるのか、
また別な解決策があれば教えていただきたいです。

問題点がよくわかっていないですが、フレーズのクエリを利用してみてはどうでしょうか?
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html

大谷さん、ありがとうございます

でも違うんです。
検索するキーワードの中に、既にあるドキュメントが完全一致してるのをヒットさせたいんです。

フレーズは、検索する文字列の話だと理解しています。

インデックスするフィールドも同じAnalyzerを利用すれば、フレーズ検索の場合は隣り合ってるものしか出てこないですよ?

あとは、こういう機能もありますね。
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-percolate-query.html

お、、なるほど。僕の理解不足です
試してみます!

@johtani
フレーズ検索で試してみました。
ドキュメントに[ 赤パジャマ, 青パジャマ, 黄パジャマ] の3つが入っているときに[赤パジャマ上]でフレーズ検索すると引っかかりません。
やりたいことは[赤パジャマ上]で検索して[赤パジャマ]をヒットさせることです。

通常の検索だと[赤パジャマ上]で検索すると[ 赤パジャマ, 青パジャマ, 黄パジャマ] がヒットします。
ここから[赤パジャマ]だけにしたいんです。
ドキュメント見ながらクエリをどう組み立てればいいか再度見てみます。

普通に検索して、その結果のドキュメントが検索する文字列に含まれてるものにプログラム内で絞る方法で一旦考えて進めます。

ngramで解析して、検索した結果が検索文字列に含まれるもののみプログラムで間引きました。

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.