0

I've got strange results when I have special characters in my query.

Here is my request :

q=histoire-france&start=0&rows=10&sort=score+desc&defType=dismax&qf=any^1.0&mm=100%

Parsed query :

<str name="parsedquery_toString">+((any:histoir any:franc)) ()</str>

I've got 17000 results because Solr is doing an OR (should be AND).

I have no problem when I'm using a whitespace instead of a special char :

q=histoire france&start=0&rows=10&sort=score+desc&defType=dismax&qf=any^1.0&mm=100%

<str name="parsedquery_toString">+(((any:histoir) (any:franc))~2) ()</str>

2000 results for this query.

Here is my schema.xml (relevant parts) :

<fieldType name="text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false">
      <analyzer type="index">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" preserveOriginal="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.CommonGramsFilterFactory" words="stopwords_french.txt" ignoreCase="true"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_french.txt" enablePositionIncrements="true"/>
        <filter class="solr.SnowballPorterFilterFactory" language="French" protected="protwords.txt"/>
        <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
        <filter class="solr.ASCIIFoldingFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <!--<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>-->
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1" preserveOriginal="0"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.CommonGramsFilterFactory" words="stopwords_french.txt" ignoreCase="true"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_french.txt" enablePositionIncrements="true"/>
        <filter class="solr.SnowballPorterFilterFactory" language="French" protected="protwords.txt"/>
        <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
        <filter class="solr.ASCIIFoldingFilterFactory"/>
      </analyzer>
    </fieldType>

I even tried with a PatternTokenizerFactory to tokenize on whitespaces & special chars but no change...

My current workaround is to replace all special chars by whitespaces before sending query to Solr, but it is not satisfying.

EDIT : Even with a charFilter (PatternReplaceCharFilterFactory) to replace special characters by whitespace, it doesn't work...

First line of analysis via solr admin, with verbose output, for query = 'histoire-france' :

org.apache.solr.analysis.PatternReplaceCharFilterFactory {replacement= , pattern=([,;./\\'&-]), luceneMatchVersion=LUCENE_32}
text    histoire france

The '-' is replaced by ' ', then tokenized by WhitespaceTokenizerFactory. However I still have different number of results for 'histoire-france' and 'histoire france'.

Did i miss something ?

4

4 に答える 4

3

'histoire-france' と 'histoire france' を検索すると、異なる数の結果が得られます。これは、クエリ パーサーが最初のケースではフレーズ クエリを作成し、2 番目のケースではブール クエリ (2 つの単語を分離する) を作成するためです。

これは明らかな動作ではありませんが、すべてのユースケースを満たすのは難しいと思います。

'histoire-france' を単に 2 つの単語として扱う検索を行うには、次のようにクエリ アナライザーの最後に" solr.PositionFilterFactory " を追加します。

  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.PositionFilterFactory" />
  </analyzer>

そうすると、「histoire-france」と「histoire france」の検索結果は同じになります。

位置フィルターは、フレーズ検索には望ましくない場合があることに注意してください (「歴史」と「フランス」の両方が存在する)。たとえば NGram フィルターで用語シーケンスを変更した場合は、代わりにクエリ slops パラメーター qs > 0 の使用を検討してください。

于 2012-02-06T18:28:25.353 に答える
1

を使用するWhitespaceTokenizerFactoryと、Solr はクエリ文字列を単語に分割します。

ただし、トークン化した後 (Solr) は、 solr.WordDelimiterFilterFactoryを使用して単語を (再び) 単語に分割します。ドキュメントを見て、Wi-Fi の例を見てください。

histoire franceそれがとのhistoire-france扱いが異なる理由の 1 つかもしれません。

2 番目: DSIMAX は (通常) クエリ用語を「用語」として処理し、(追加で) 解析済み文字列としても処理することを忘れないでください。

問題を解決するには、ワールド区切り文字を回避し、使用して「トークン化」を処理しようとすることができますPatternTokenizerFactory(以前に試したように、現在は WordDelimiterFilterFactory を使用していません)。

それでもうまくいかない場合は、analysys.jsp の完全な出力を投稿してみてください。

于 2011-10-25T15:02:35.790 に答える
1

それはバグでした: https://issues.apache.org/jira/browse/SOLR-3589

edismax mm を 100% に設定すると、トークンの 1 つがアナライザー チェーンによって 2 つのトークンに分割される場合 (つまり、"fire-fly" => fire fly)、mm パラメーターは無視され、"fire OR fly" の OR クエリと同等になります。 " は生産された。これは、中国語や日本語など、単語を区切るために空白を使用しない言語で特に問題になります。

Solr 4.1 (2013 年 1 月 22 日) で修正されました。

于 2013-01-24T09:38:42.763 に答える
0

autoGeneratePhraseQueries を true に有効にすると、フレーズ クエリが生成されます。
したがって、histoire-franc を検索すると、引用符付きのクエリが生成され、両方の単語をフレーズとして含むドキュメントのみが一致します。

<str name="parsedquery">(+DisjunctionMaxQuery(((any:histoire any:franc))))/no_coord</str>

作業構成の例 -

<fieldType name="text_test" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
  <analyzer type="index">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

クエリ slop を使用qs=10して、フレーズ クエリなどでスロップの数を指定します。

<str name="parsedquery">(+DisjunctionMaxQuery((any:"histoire france"~10)))/no_coord</str>
于 2011-10-25T18:22:37.437 に答える