0

Lucene 3.6.1 を使用しています。ユーザーからクエリを受け取ります。このクエリには、+または-演算子が含まれる場合があり、フレーズが含まれる場合もあります。特定の状況では、計算する用語を追加してクエリを拡張したいと考えています。これらの用語はオプションです。ただし、ユーザーが指定した必要な包含/除外制約はすべて尊重する必要があります。

私の最初の戦略は、 を作成しBooleanQuery、解析されたユーザー クエリを含む句をそれに追加し、拡張用語を含む句をさらに追加することでした。展開項はすべて として追加されOccur.SHOULDます。私の質問は、ユーザーのクエリを制限する方法です。次の 3 つの可能性を想像できます。

  1. Occur.SHOULDユーザーのクエリには演算子が含まれていません。つまり、句として含めることができます。

  2. ユーザーのクエリには+演算子が含まれているため、それをOccur.MUST句として含める必要があります。

  3. ユーザーのクエリには-演算子が含まれていますが、他の用語も含まれています。それをOccur.MUST句として含めますか?

これら 3 つの選択肢に内在する問題は、どの条件が適切であるかをどのように判断するかということです。クエリを書き直してBooleanQueryインスタンスをテストできると思いますが、それは脆いようです。

次のように、ユーザーの入力と私の拡張用語から単一の文字列を作成する戦術を試すこともできると思います。

(fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...

これが最善の方法ですか?または、エレガントなプログラムによる解決策はありますか?

4

1 に答える 1

0

さて、この答えがどれほど役立つかはわかりませんが、ここで難しい答えを思いつくことができないようです.

まず、問題:

クエリを次のように変更します。

(userquery) (other) (stuff)

あなたが示したルールに + を追加することはある程度理にかなっていますが、「-」禁止用語は、禁止用語が(query -prohibition) (other)存在する他のものとの一致も許可し、+(query -prohibition) (other)「クエリ」の一致が必要になるため、正しく尊重するのが難しくなります。 .

その部分を本当に正しく行う唯一の方法は、禁止用語を自動的に追加された用語にも伝播するか、(query -prohibition)-->のように親クエリレイヤーに抽出すること(query) (other) -(prohibition)です。

また、任意の複雑さのユーザー入力クエリでは、それは優れた戦略ではない可能性があります。


クエリ文字列を変更して対処したい場合は、クエリの末尾に任意の用語を追加する必要があります。それ以上のことはありません。

私は信じません

(fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...

userterm4 はそのサブクエリ内でのみ必要とされるため、満足のいくものですが、expterm1 でのみ一致することは引き続き許容されます。ただし、次のようなクエリ:

fld1:userterm1 userterm2 -fld2:userterm3 +userterm4 (fld1:expterm1)^.8 (fld2:expterm2)^.7 ...

あなたのニーズを満たし、クエリパーサーの内部について心配する必要がないようにすべきだと思います。 これが最善のアプローチだと思います。


次のような構造のクエリでロジックも確認できます

+(parsed userquery) (other stuff)

事実上、常にユーザー クエリに一致する必要があります。Lucene は、クエリに必須フィールドが存在しない場合でも、用語に一致しない結果を返さないため、ある意味では暗黙的にこれを行います。これは、より大きなドキュメント セットを返すのではなく、追加した用語を使用してスコアリングに影響を与えることになります。これはあなたの質問に完全には対応していませんが、検討する価値があるかもしれません。


前述の問題にもかかわらず、「+」演算子と「-」演算子を検出したい場合は、チェックする必要があるクエリに対して、StandardQueryParser が基本レベルで BooleanQuery を返すと合理的に想定できると思います。これらのオペランドをオンにします。たとえば、DisjunctionMaxQueries について心配する必要があるかもしれません。また、次のような演算子を使用した単純なクエリがある場合に何が起こるかについても心配する必要があります。

+myterm

QueryParser が単純に TermQuery を返し、プラスを失うかどうかはわかりません (別の用語が存在しないと冗長になるため)。そのような懸念があると、このように対処することを躊躇します。

同様に、クエリ文字列からこれらの値を検出しようとすると、物事がどのように解析されるかについて仮定する必要があり、複雑になる可能性があります。


要約すると、最適なオプションは、解析を行う前に生のクエリ文字列の末尾に用語を追加するか、ユーザークエリをアトミックとして扱い、ブール値に追加するときにその内容に依存しない適切なブール句を定義することです。含める必要がある他のクエリでそれをラップする句。

于 2012-12-06T06:59:45.277 に答える