2

私は lucene 3.5 をSpanishAnalyzerで使用しています (それ自体は SpanishStemmerStandardTokenizerを使用しています)。
SpanishAnalyzer が "claramente" と "claro" などの単語を含むドキュメントをインデックス化すると、両方とも "clar" としてインデックス化されます。
この動作は理解されており、私のニーズに役立ちます。今日、クエリを実行する前に、Analyzer のtokenStream+incrementToken()を使用して検索語のトークンを取得し、それをインデックス付きドキュメントに対して検索します。私は QueryParser を使用していませんが、コードで lucene クエリ オブジェクトを作成しています。
ただし、SpanishAnalyzer の形態学的機能を失うことなく、正確な単語 (この例では claro) を検索する機能が必要です。
上記の手順 (tokenStream) をスキップして「claro」を直接検索できますが、「clar」としてインデックス付けされているため見つかりません。また、1 つの正確な単語と 1 つの通常の用語 (形態学的) を含むorを
使用する機能が必要なため、2 つの異なるアナライザーでフィールドを 2 回インデックス付けしたくありません。 それで…そして私は要点に達しています…トークナイザーまたはステマーまたはフィルター(?)を変更することを考えたので、インデックス作成時に、語幹が付けられたトークンと元のトークンの2つのトークンがインデックス付けされます。この場合は「claro " および "clar" 以降、クエリを実行するときに、正確な単語を使用するか、語幹の付いたトークンを使用するかを選択できます。 どのように (そしてどこで) それを行うことができるかを理解する助けが必要です。編集は Stemmer のどこかで行う必要があると思います。 PhraseQuerySpanNearQuery

ちなみに、使用時にテキスト内の単語ごとにいくつかのトークンを返すヘブライ語アナライザーでまったく同じことを行いますincrementToken()(ただし、ソースコードはありません)

4

2 に答える 2

3

語幹のあるトークンと語幹のない (=元の) トークンが混在するフレーズを検索したいので、位置ごとに複数のトークンを持つインデックスが必要です。バージョン 5.3 について回答しますが、3.5 もそれほど違いはありませんでした。

solrのReversedWildcardFilterのソース コードを見てください。各トークンに次の 2 つのステップが表示されます。

  1. 元のトークンで現在の状態を保存します。したがって、incrementToken()メソッドの最初の呼び出しはステム化されたトークンに到達し、2 番目の呼び出しは元のトークンに到達します (同じ位置で)
  2. ステミングされたトークンのプレフィックスとして「markerChar」を選択します。そのため、検索時に、語幹付きトークンまたは元のトークンで検索するかどうかを決定できます。

あなたのSpanishAnalyzerの場合、これは例えば以下を意味します:

SpanishAnalyzer のコアは、SpanishLightStemFilter です。SpanishLightStemFilter は、 !KeywordAttribute.isKeyword()を使用して Token のみをステミングしました。そのため、インデックス時の場合は、SpanishAnalyzer に KeywordRepeatFilter を挿入し、語幹を付けたトークンにプレフィックスを付けます。

于 2015-12-27T23:15:01.153 に答える
0

これを非常に簡単に有効にするトークン フィルターがあります。 KeywordRepeatFilter(SpanishLightStemFilter KeywordAttribute を尊重します)。Stemmer の直前に分析チェーンに追加するだけです。SpanishAnalyzer の場合、createComponentsメソッドは次のようになります。

@Override
protected TokenStreamComponents createComponents(String fieldName) {
    final Tokenizer source;
    if (getVersion().onOrAfter(Version.LUCENE_4_7_0)) {
        source = new StandardTokenizer();
    } else {
        source = new StandardTokenizer40();
    }
    TokenStream result = new StandardFilter(source);
    result = new LowerCaseFilter(result);
    result = new StopFilter(result, stopwords);
    if(!stemExclusionSet.isEmpty())
        result = new SetKeywordMarkerFilter(result, stemExclusionSet);
    result = new KeywordRepeatFilter(result);
    result = new SpanishLightStemFilter(result);
    return new TokenStreamComponents(source, result);
}

これにより、ステム処理されていない用語のみを明示的に検索することはできませんが、元の用語がステムと同じ位置に保持されるため、フレーズ クエリに簡単に組み込むことができます。語幹付きの用語のみ、または語幹なしの用語のみを明示的に検索する必要がある場合は、別のフィールドでインデックスを作成する方が実際には優れた方法です。

于 2015-12-28T05:07:22.107 に答える