6

ユーザーが車の部品を選ぶことができるアプリケーションがあります。彼らは車両を選択し、次に車両属性をファセットとして選択します。車両を選択した後、エンジン サイズなどのファセットを選択して、結果のリストを絞り込むことができます。問題は、すべてのドキュメントにエンジン サイズがあるわけではないことです (Solr では空の値です)。たとえば、エンジンのサイズがエア フィルターにとって重要になることはめったにありません。そのため、ユーザーがエンジン サイズで 3.5L を選択したとしても、ユーザーが選択できる可能性のある部品としてエア フィルターを画面に表示したかったのです。いくつかの検索を行ったところ、次のファセット クエリは完全に機能します。

enginesize:"3.5" OR enginesize:(*:* AND -enginesize:[* TO *]) 

このクエリは、3.5 に一致するか、エンジン サイズ フィールドに値がないレコードに一致します (値がないということは、重要ではなく、車に適合することを意味します)。完全...

問題: 最近、車両属性フィールドを多値フィールドにしたので、各パーツの属性をリストとして保存できました。次に、ファセットを適用すると、うまくいきました。ただし、前述のクエリを適用すると問題が発生しました。enginesize ファセットを選択すると、表示されるドキュメントの数がそのエンジン サイズを持つドキュメントのみに絞り込まれますが、enginesize の値が空の (つまり "") を持つレコード (ドキュメントという意味でもレコードを使用します) は表示されませんでした。上記の同じクエリは、enginesize が単一値フィールドの場合と同じように、多値ファセットには機能しません。

例:

 <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 を引き戻すクエリです。最初のドキュメント (エンジン マウント) は一致します。これは、探している多値フィールド「enginesize」の 1 つに値が含まれているためです (フィールドの 1 つに 3.5 が含まれています)。<str>ただし、エア フィルターの 3 番目のドキュメントは、空の値のため返されません。ファセット値と一致しないため、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:"")

空白の値としてスペースがある場合でも、単に値がまったくない場合でも、どちらの状況でも機能するクエリを誰かが持っていますか?

4

3 に答える 3

8

クエリの方法ではなく、インデックスの方法を変更するのはどうですか?

「エンジンのサイズは関係ありません」を空のレコードとしてインデックス化しようとする代わりに、「ANY」としてインデックス化します。

次に、クエリは単純に enginesize:"3.5" OR (enginesize:ANY) になります。

于 2010-02-19T19:14:30.163 に答える
1

私はちょうどこれで遊んでいて、私のためにトリックを行うように見えるヒントを見つけました. クエリに翻訳すると、次のようになります。

enginesize:"3.5" OR (-enginesize:["" TO *])

h番目、

そして私


更新:さらにテストした後、これが確実に機能するとは思いません。一部のインデックスでは、マイナス記号なしで逆にする必要がありましたenginesize:[* TO ""]。これは、複数値の場合、または実際の値にさえ依存する場合、インデックスの種類に依存する可能性があります。

いずれにせよ、ハックが多すぎるようです。私はおそらく、空の値を特別なマーカーで置き換えることに解決するでしょう...

于 2010-03-02T16:49:10.260 に答える