0

(より具体的な問題の詳細については、以下の更新を参照してください) 非常に長いドキュメント フィールドの値があります。これらのフィールドのトークンの形式は、word|payload|position_increment です。(位置の増分とペイロードを手動で制御する必要があります。) ドキュメント全体のこれらの複合トークンを収集し、'\t' で結合してから、この文字列をカスタム アナライザーに渡します。(非常に長いフィールド文字列の場合、UnicodeUtil.UTF16toUTF8() で ArrayOutOfBoundsException で何かが壊れます)。

アナライザーは次のとおりです。

class AmbiguousTokenAnalyzer extends Analyzer {
    private PayloadEncoder encoder = new IntegerEncoder();

    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
        Tokenizer source = new DelimiterTokenizer('\t', EngineInfo.ENGINE_VERSION, reader);
        TokenStream sink = new DelimitedPositionIncrementFilter(source, '|');
        sink = new CustomDelimitedPayloadTokenFilter(sink, '|', encoder);
        sink.addAttribute(OffsetAttribute.class);
        sink.addAttribute(CharTermAttribute.class);
        sink.addAttribute(PayloadAttribute.class);
        sink.addAttribute(PositionIncrementAttribute.class);
        return new TokenStreamComponents(source, sink);
    }
}

CustomDelimitedPayloadTokenFilter と DelimitedPositionIncrementFilter には、トークンの右端の「|aaa」部分が処理される「incrementToken」メソッドがあります。

フィールドは次のように構成されます。

attributeFieldType.setIndexed(true);
attributeFieldType.setStored(true);
attributeFieldType.setOmitNorms(true);
attributeFieldType.setTokenized(true);
attributeFieldType.setStoreTermVectorOffsets(true);
attributeFieldType.setStoreTermVectorPositions(true);
attributeFieldType.setStoreTermVectors(true);
attributeFieldType.setStoreTermVectorPayloads(true);

問題は、アナライザーにフィールド自体 (1 つの巨大な文字列 - document.add(...) 経由) を渡すと問題なく動作しますが、トークンを次々と渡すと、検索段階で何かが壊れます。どこかで読んだように、これらの 2 つの方法は、結果として得られるインデックスの観点からは同じでなければなりません。多分私のアナライザーは何かを見落としていますか?

アップデート

これが私の問題の詳細です。インデックス作成に加えて、複数値フィールドをそのまま保存する必要があります。複数のアトミック トークンとしてアナライザーに渡すと、最初のトークンのみが格納されます。最終的に連結されたすべてのアトミック トークンをカスタム アナライザーに格納するには、何を行う必要がありますか?

4

1 に答える 1

0

さて、すべての値が実際に格納されていることがわかります。インデックス作成後に得られるものは次のとおりです。

indexSearcher.doc(0).getFields("gramm")

stored,indexed,tokenized,termVector,omitNorms<gramm:S|3|1000>
stored,indexed,tokenized,termVector,omitNorms<gramm:V|1|1>
stored,indexed,tokenized,termVector,omitNorms<gramm:PR|1|1>
stored,indexed,tokenized,termVector,omitNorms<gramm:S|3|1>
stored,indexed,tokenized,termVector,omitNorms<gramm:SPRO|0|1000 S|1|0>
stored,indexed,tokenized,termVector,omitNorms<gramm:A|1|1>
stored,indexed,tokenized,termVector,omitNorms<gramm:SPRO|1|1000>
stored,indexed,tokenized,termVector,omitNorms<gramm:ADV|1|1>
stored,indexed,tokenized,termVector,omitNorms<gramm:A|1|1>

そして「シングルフィールド」バージョン

indexSearcher.doc(0).getField("gramm")

stored,indexed,tokenized,termVector,omitNorms<gramm:S|3|1000>

getField() が最初の値のみを返す理由はわかりませんが、私のニーズでは getFields() は問題ないようです。

于 2013-10-05T10:25:30.657 に答える