多額のファセットフィールドと同時にSOLRで空白のファセットを検索するにはどうすればよいですか?
-
20-09-2019 - |
質問
ユーザーが車の部品を選ぶことができるアプリケーションがあります。彼らは車両を選び、車両の属性をファセットとして選びます。車両を選択した後、たとえば結果のリストを絞り込むために、エンジンサイズなどのファセットを選択できます。問題は、すべてのドキュメントがエンジンサイズ(SOLRの空の値である)を持っているわけではないということでした。これは、すべての部品に関係ないためです。たとえば、エアンフィルターではエンジンサイズが重要ではありません。したがって、ユーザーがエンジンサイズで3.5Lを選んだとしても、ユーザーが選択できる部分として画面にエアフィルターを表示したかったのです。私はいくつかの検索を行いました、そして、次のファセットクエリは完全に機能します:
enginesize:"3.5" OR enginesize:(*:* AND -enginesize:[* TO *])
このクエリは、3.5と一致するか、エンジンサイズのフィールドに値がないレコードと一致します(値は問題ではなく、車に合っています)。完全...
問題: :私は最近、車両属性フィールドをマルチバリューフィールドに作成したので、各部品の属性をリストとして保存できます。その後、ファセットを適用しましたが、うまくいきました。ただし、前述のクエリを適用したときに問題が発生しました。エンジンのファセットを選択している間、そのエンジンサイズを持つドキュメントのみに表示されるドキュメントの数を絞り込んで、エンジンの空の値(すなわち "")を持つレコード(私もドキュメントを意味する」という単語レコードを使用しています)は表示されませんでした。上記の同じクエリは、エンジンが単一の価値のあるフィールドである場合と同じように、多面的なファセットでは機能しません。
例:
<doc>
<str name="part">engine mount</str>
<arr name="enginesize">
<str/>
<str/>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
</arr>
<doc>
<doc>
<str name="part">engine bolt</str>
<arr name="enginesize">
<str>6</str>
<str>6</str>
<str>6</str>
<str>6</str>
<str>6</str>
</arr>
<doc>
<doc>
<str name="part">air filter</str>
<arr name="enginesize">
<str/>
<str/>
<str></str>
<str></str>
<str></str>
<str></str>
<str></str>
</arr>
<doc>
私が探しているのは、3.5でエンジンサイズをファセット検索するときに上記のドキュメント1と3を引き戻すクエリです。最初のドキュメント(エンジンマウント)は一致します。これは、私が探している(フィールドの1つに3.5を含む)「エンジン」のマルチバリューフィールドの1つに値が含まれているためです。ただし、空のためにエアフィルターの3番目のドキュメントは返されません <str>
値。ファセット値と一致しないため、2番目のドキュメントをまったく返したくありません
基本的に、特定のファセットの空の文字列値と一致し、実際の値と一致するクエリが必要なので、両方のドキュメントを返します。
誰かがドキュメント1とドキュメント3(エンジンブラケットとエアフィルター)を返すクエリを持っていますが、エンジンボルトドキュメントではありませんか?
私は成功せずに以下を試しました(この質問の最上位にあるものを含む):
// returns everything
enginesize:"3.5" OR (enginesize:[* TO *] )
// only returns document 1
enginesize:"3.5" OR (enginesize:["" TO ""] AND -enginesize:"3.5")
// only returns document 1
enginesize:"3.5" OR (enginesize:"")
CSVファイルを使用して上記のデータをインポートし、フィールドを設定しました keepEmpty=true
. 。代わりに、CSVファイルを生成したときにフィールドにスペースを手動で挿入しようとしました(これにより <str> </str>
, 、以前の代わりに、クエリを再試行しました。そうすることで、次の結果が得られました。
// returns document 1
enginesize:"3.5" OR enginesize:(*:* AND -enginesize:[* TO *])
// returns all documents
enginesize:"3.5" OR (enginesize:["" TO ""] AND -enginesize:"3.5")
// returns all documents
enginesize:"3.5" OR (enginesize:"")
私が空白の値としてスペースを持っているか、単に値がまったくないかにかかわらず、どちらの状況でも機能するクエリを持っていますか?
解決
クエリの代わりに、インデックスを変更する方法を変更してみませんか?
「エンジンサイズは重要ではない」を空のレコードとしてインデックス化しようとする代わりに、「任意」としてインデックスを付けます。
次に、クエリは単にエンジンになります: "3.5"または(エンジンズ:任意)
他のヒント
私はちょうどこれで遊んでいて、aを見つけました ヒント それは私にとってトリックをしているようです。あなたのクエリに翻訳するべきです:
enginesize:"3.5" OR (-enginesize:["" TO *])
Hth、
そして私
更新:さらにいくつかのテストの後、これが確実に機能するとは思いません。一部のインデックスでは、標識がマイナスのない逆でなければなりませんでした。 enginesize:[* TO ""]
. 。これは、多値である場合、あるいは実際の値である場合、インデックスタイプに依存する場合があります。
いずれにせよ、それはあまりにもハックのようです。私はおそらく、空の値を特別なマーカーで置き換えることを決意します...
私は同じ問題を抱えていましたが、それを解決しました https://stackoverflow.com/a/35633038/13365:
enginesize:"3.5" OR (*:* NOT enginesize:["" TO *])
-enginesize
解決策は私にはうまくいきませんでした。