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);

问题是,如果我将字段本身(一个巨大的字符串 - 通过 document.add(...) )传递给分析器,它可以正常工作,但是如果我在一个令牌之后传递令牌,则在搜索阶段会出现问题。正如我在某处读到的,从结果索引的角度来看,这两种方式必须相同。也许我的分析仪遗漏了什么?

更新

这是我更详细的问题:除了索引之外,我还需要按原样存储多值字段。如果我将它作为多个原子令牌传递给分析器,它只会存储其中的第一个。我需要对我的自定义分析器执行什么操作以使其存储最终连接的所有原子标记?

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 回答