このクエリを最適に構成する方法は何ですか?

トピック作成者:ks-solruserml-bot (2024/07/06 12:34 投稿)
6
CloseClose

(The bot translated the original post https://lists.apache.org/thread/7v74vftg38l8x5o7och86256yb47yd61 into Japanese and reposted it under Apache License 2.0. The copyright of posted content is held by the original poster.)

こんにちは、

もしかしたら答えは明白で私が何か見落としているのかもしれませんが、お伺いします。

あるフィールドにセットから1つ以上のトークンを含む文字列があるとします。そのセットには約50の可能な値があり、値自体は任意です(ただし、事前にわかっており、必要であればアルファベット順に並べることができます)。例:

  • doc1: "red"
  • doc2: "blip red"
  • doc3: "aardvark blip red"
  • doc4: "aardvark potato"

クエリに指定されたトークンの少なくとも1つを含むドキュメントをフィールドで検索し、クエリにないトークンは含まないようにしたいと考えています。このためには最適なクエリは何でしょうか?

例えば、次のクエリを実行すると:

  • "red" は上記のdoc1のみに一致するべきです
  • "blip red" はdoc1とdoc2の両方に一致するべきです
  • "blip red potato" もdoc1とdoc2に一致するべきです
  • "aardvark blip" は上記のいずれのドキュメントにも一致しないべきです。これが一致するには "red" も必要です。
  • "aardvark blip red potato" はすべてのドキュメントに一致するべきです。

オプション?

  1. クエリを全ての必要なトークンを含むようにし、セット内の他のトークンを否定するようにすることができます。例えば、"blip red" は "+(blip red) -(aardvark potato....)" になり、"red" は "+(red) -(aardvark blip potato...)" になります。セットのサイズは固定なので、クエリ内の用語の数は変わりません。含めるか除外するかだけが変わります。しかし、全ての否定を指定するのは非効率的に思えます。
  2. データのインデックス方法を変更して、フィールドを決定論的に連結し、単一の値としてトークン化し、用語の組み合わせをクエリすることができます。例えば、"blip red" は "blip red blip-red" になりますが、いくつかの用語があるとファンアウトが大きくなります。例えば、"aardvark blip red" は "aardvark blip red aardvark-blip aardvark-red blip-red aardvark-blip-red" など、(2^N)-1の組み合わせになります。

オプション1は用語の数に関係なくかなり一定ですが、少数の用語では無駄が多くなります。一方、オプション2は10用語のクエリで1000以上の組み合わせを生成します。これはLuceneにとって実際に問題でしょうか?20用語では100万以上の組み合わせを生成しますが、それは問題のように思えます。しかし、そのような多数の用語を含むクエリは必要ないかもしれません。

私は1に傾いていますが、それは悪い解決策でしょうか?見落としている良いオプションはありますか?

関連する質問として、EnumFieldTypeは他のフィールドタイプよりも効率的なクエリを可能にするか、または明示的なソートを提供するだけでしょうか?つまり、多値のEFTはこの場合により良いでしょうか?

ありがとうございます、
Colvin

返信投稿者:(2024/07/06 12:37 投稿)
(この投稿は削除されました)
返信投稿者:ks-solruserml-bot (2024/07/06 12:59 投稿)

こんにちは、Colvin。

通常、例えば1,000以上の用語を一度にクエリすることはありません。なぜなら、そのクエリは高コストになる可能性があるからです。

ここで、少し変わったアイデアを提案します:単語をアルファベット順に並べ替えた数字にマップすることです。例えば:

  • aardvark - 1
  • blip - 2
  • potato - 3
  • red - 4

クエリを作成するときに、同じ変換を行い、用語を並べ替えて、次のようなものを検索します:

  • 任意の単語
  • それらの間の範囲を否定

例えば、"red potato" を検索する場合、クエリは次のようになります:

(3 OR 4) -{* TO 3} -{3 TO 4} -{4 TO *}

3から4の範囲(排他的)を追加したことに注意してください。これは意味をなさないかもしれませんが、単純な実装ではいくつかの数字が連続しているかどうかを確認し、意味のない範囲を削除することはありません。これは最適化です。

よろしくお願いします、
Radu

Sematext Cloud - フルスタック観測
https://sematext.com/

返信投稿者:ks-solruserml-bot (2024/07/06 12:59 投稿)

Raduさん、それはおもしろい提案です。ありがとうございます。

返信投稿者:ks-solruserml-bot (2024/07/06 13:08 投稿)

こんにちは、Colvin。

この問題はPercolatorマッチロジックを思い出させます。ElasticやSolr用のそのようなプラグインの話を聞いたことがあります。

Dismaxのmin_should_match(mm)について考えてみてください。特定のフィールドに多数の単語をインデックス付けし、定数スコアを使用して各用語のヒットをカウントし、ヒットスコアを合計し、弱いカバレッジのマッチを{!frange}(スコアの合計をトークン数フィールドと比較)を使って切り捨てます。数年前にコメントやリストで議論されました。すでにそれに向かって進んでいるかどうかはわかりません。また、そのようなロジックがElasticsearchに組み込まれていることも覚えています。

参考: Elasticsearch - Terms Set Query

--
よろしくお願いします、
Mikhail Khludnev

返信投稿者:ks-solruserml-bot (2024/07/06 13:08 投稿)

以下のディスカッションを参照してください:

--
よろしくお願いします、
Mikhail Khludnev

返信投稿者:ks-solruserml-bot (2024/07/06 13:08 投稿)

Mikhailさん、ご提案ありがとうございます。

トピックへ返信するには、ログインが必要です。

KandaSearch

Copyright © 2006-2024 RONDHUIT Co, Ltd. All Rights Reserved.

投稿の削除

この投稿を削除します。よろしいですか?