我用一个使用LuceneTestCase的文档制作了最简单的索引。我的目标是为每个术语的每个位置写入有效负载的数字,这将用于自定义Query / Scorer中实现的自定义评分公式。
我使用SimpleTextCodec并检查,freq,position和payload真正写入索引。
但是当我从PostingEnum读取freq时它返回0,payload()返回null,nextPosition()抛出异常:
java.lang.AssertionError: got line=field model
at __randomizedtesting.SeedInfo.seed([D334C9D1B5C155E3:2AAE4BE5481F4C8F]:0)
at
org.apache.lucene.codecs.simpletext.SimpleTextFieldsReader$SimpleTextPostings Enum.nextPosition(SimpleTextFieldsReader.java:455)
以下是我在自定义查询中阅读帖子的方法:
for (String field: fieldScores.keySet()) {
final Terms fieldTerms = reader.terms(field);
if (fieldTerms == null) {
continue;
}
if (!fieldTerms.hasPositions())
throw new IllegalStateException("Index does not contain positions");
if (!fieldTerms.hasPayloads())
throw new IllegalStateException("Index does not contain payloads");
final TermsEnum te = fieldTerms.iterator();
for (int j = 0; j < terms.length; j++) {
final Term t = terms[j];
if (t.field().equals(field) && te.seekExact(t.bytes())) {
PostingsEnum postingsEnum = te.postings(null, PostingsEnum.ALL);
int pos = postingsEnum.nextPosition();
BytesRef payload = postingsEnum.getPayload();
// assert payload.bytesEquals(new BytesRef(new byte[]{1}));
// TODO: use payload in scoring formula
fldScorers.add(new ConstTermScorer(this, t,
fieldScores.get(field) * termScores.get(t.text()),
postingsEnum));
}
}
}
答案 0 :(得分:0)
我找到了原因。 nextPosition(),freq()和payload()返回0(或null)值,因为postssEnum(iterator)刚刚创建并且尚未定位在具体文档上。 postssEnum.nextDoc()没有被调用,且postssEnum.docID()是-1。愚蠢的情况,但如果nextPosition(),freq()和payload()检查postsEnum.docID会更好。