es版本:7.10.2
目的:重写打分规则,想要保证搜索字符串在原始字符串越前,排序就约靠前。
做法:核心是实现ScoreScript接口,主要是获取postion。代码如下:
@Override
public void setDocument(int docid) {
super.setDocument(docid);
try {
// 根据docid和field获取terms的信息,这里会取到多个term。实现见:CompressingTermVectorsReader
Terms terms = ctx.reader().terms(field);
// Terms terms = ctx.reader().getTermVector(docid, field);
logger.info("ctx={},docid={}, terms={}", ctx, docid,terms);
if (terms != null) {
for (String query : queryList) {
String term = getFirstMatchStr(query);
TermsEnum termsEnum = terms.iterator();
for (int i = 0; i < terms.size(); i++) {
// 遍历
String termOrigin = termsEnum.next().utf8ToString();
PostingsEnum postings = termsEnum.postings(null, PostingsEnum.ALL);
postings.nextDoc();
if (termOrigin.startsWith(term)) {
int position = postings.nextPosition();
if (position < firstMatchPosition) {
termDesc.add("curFirstPosition=" + firstMatchPosition + "命中term=" + termOrigin + position);
firstMatchPosition = position + 1;
}
// 检查到最靠前匹配的分词,结束遍历
break;
}
}
}
}
} catch (IOException e) {
logger.error("docid:{},field:{},query:{},get payload error!,stack:{}", docid, field, queryList, e);
}
}
但这样我发现所有的doc的firstMatchPosition都是一样的。比如小火花和小花,搜索花的时候计算出来的firstMatchPosition都是1。不知道哪里获取不对
目的:重写打分规则,想要保证搜索字符串在原始字符串越前,排序就约靠前。
做法:核心是实现ScoreScript接口,主要是获取postion。代码如下:
@Override
public void setDocument(int docid) {
super.setDocument(docid);
try {
// 根据docid和field获取terms的信息,这里会取到多个term。实现见:CompressingTermVectorsReader
Terms terms = ctx.reader().terms(field);
// Terms terms = ctx.reader().getTermVector(docid, field);
logger.info("ctx={},docid={}, terms={}", ctx, docid,terms);
if (terms != null) {
for (String query : queryList) {
String term = getFirstMatchStr(query);
TermsEnum termsEnum = terms.iterator();
for (int i = 0; i < terms.size(); i++) {
// 遍历
String termOrigin = termsEnum.next().utf8ToString();
PostingsEnum postings = termsEnum.postings(null, PostingsEnum.ALL);
postings.nextDoc();
if (termOrigin.startsWith(term)) {
int position = postings.nextPosition();
if (position < firstMatchPosition) {
termDesc.add("curFirstPosition=" + firstMatchPosition + "命中term=" + termOrigin + position);
firstMatchPosition = position + 1;
}
// 检查到最靠前匹配的分词,结束遍历
break;
}
}
}
}
} catch (IOException e) {
logger.error("docid:{},field:{},query:{},get payload error!,stack:{}", docid, field, queryList, e);
}
}
但这样我发现所有的doc的firstMatchPosition都是一样的。比如小火花和小花,搜索花的时候计算出来的firstMatchPosition都是1。不知道哪里获取不对
3 个回复
QuincyXuHa - 90后
赞同来自:
Terms terms = ctx.reader().terms(field);
这个返回的结果在本地是当前doc字段的内容,在qa集群上是整个索引的doc内容,这是咋回事
QuincyXuHa - 90后
赞同来自:
ScoreScript的属性初始化直接放在属性上了,应该放在setDocument里面的,保证每次处理doc的时候都是初始化值而不是之前的值。
Ombres
赞同来自:
常规用法是获取到term的postings,然后postings.advance(docid),再进行相关操作。
另外感觉很多情况下性能会比较差啊,如果LeafReader中term较多,对每篇命中的文章过一遍所有的term。