Java 索尔:搜索排除更大的短语
F.e.我有3份文件。Java 索尔:搜索排除更大的短语,java,lucene,solr,Java,Lucene,Solr,F.e.我有3份文件。 1.“狗猫球” 2.“狗狗球猫” 3.“狗、猫、球和大象” 所以。通过查询“狗、猫和球”,我只希望收到前两个文档。 所以我想在结果中只包含我要求的词的主要思想 如有任何建议,我将不胜感激。 谢谢。好的,如果您存储TermVector(在创建字段时,在将文档添加到索引之前,使用TermVector。是的),可以通过覆盖收集器来完成。下面是一个简单的实现(只返回没有分数的文档): 私有静态类MyCollector扩展收集器{ 私有索引阅读器; 专用术语; 私有集=新的Hash
1.“狗猫球”
2.“狗狗球猫”
3.“狗、猫、球和大象” 所以。通过查询“狗、猫和球”,我只希望收到前两个文档。
所以我想在结果中只包含我要求的词的主要思想 如有任何建议,我将不胜感激。
谢谢。好的,如果您存储TermVector(在创建
字段时,在将文档添加到索引之前,使用TermVector。是的
),可以通过覆盖收集器来完成。下面是一个简单的实现(只返回没有分数的文档):
私有静态类MyCollector扩展收集器{
私有索引阅读器;
专用术语;
私有集=新的HashSet();
公共MyCollector(IndexReader ir,国际术语编号){
this.ir=ir;
this.numberOfTerms=numberOfTerms;
}
@凌驾
public void setScorer(Scorer Scorer)抛出IOException{}//在本例中我们不使用Scorer
@凌驾
public void setnextrader(IndexReader阅读器,int docBase){
//忽略
}
@凌驾
公共void collect(int doc)引发IOException{
TermFreqVector=ir.getTermFreqVector(文档,内容\字段);
//CONTENT_field是您正在搜索的字段的名称。。。
如果(向量!=null){
if(vector.getTerms().length==numberOfTerms){
设置、添加(单据);
}
}否则{
set.add(doc);//好吧,假设这不会发生,因为您存储了TermVector。
}
}
@凌驾
公共布尔值AcceptsDocSoutoOrder(){
返回true;
}
公共集getSet(){
返回集;
}
};
现在,使用IndexSearcher\search(查询,收集器)
其思想是:如果要接受文档,您知道文档中应该包含多少术语,因此您只需验证它,并只收集符合此规则的文档。当然,这可能更复杂(在向量中查找特定的术语,在向量中单词的顺序),但这是一般的想法
实际上,如果您存储TermVector,您几乎可以做任何事情,因此只需尝试使用它。您可以实现一个具有哈希功能的过滤器工厂/标记器对
使用copyfield指令
您需要标记术语
删除stopwords(在您的示例中)
按字母数字顺序对术语排序并保存哈希
展开查询以同时搜索哈希值,如:
somestring:“狗、猫和球”和somehash:“狗、猫和球”
第二个searchquery部分将在查询处理中隐式散列
这只会导致精确匹配(假阳性概率非常不现实)
另外,您不需要存储术语向量。这将导致明显较小的索引。您的问题是什么?为什么“狗、猫和球”对你不起作用?我不需要smth的文件,只需要狗、猫和球。所以我不需要搜索结果中的第三个案例。你可以做+狗+猫+球-大象。(或“…和(不是大象)”)但你必须明确排除你不想要的每个词。所以。。。您的意思是-后期处理?@denys:Collector\collect(int docID)
被调用如果文档与搜索()中的查询匹配,您只需使用它筛选结果,因此它是在处理过程中调用的。@amit非常感谢您。我明白你的意思。现在你能告诉我在Solr中在哪里可以使用IndexSearcher吗?我应该将我的更改添加到SolrIndexSearcher?@denys:SolrIndexSearcher扩展了IndexSearcher(org.apache.lucene.search.IndexSearcher),因此您可以更改SolrIndexSearcher,或者使用IndexSearcher的搜索(而不是SolrIndexSearcher中新的重载搜索)。@amit谢谢。每个解决方案都意味着我应该改变解决方案。但我不想这样做:(。。。
private static class MyCollector extends Collector {
private IndexReader ir;
private int numberOfTerms;
private Set<Integer> set = new HashSet<Integer>();
public MyCollector(IndexReader ir,int numberOfTerms) {
this.ir = ir;
this.numberOfTerms = numberOfTerms;
}
@Override
public void setScorer(Scorer scorer) throws IOException { } //we do not use a scorer in this example
@Override
public void setNextReader(IndexReader reader, int docBase) {
//ignore
}
@Override
public void collect(int doc) throws IOException {
TermFreqVector vector = ir.getTermFreqVector(doc, CONTENT_FIELD);
//CONTENT_FILED is the name of the field you are searching in...
if (vector != null) {
if (vector.getTerms().length == numberOfTerms) {
set.add(doc);
}
} else {
set.add(doc); //well, assume it doesn't happen, because you stored your TermVectors.
}
}
@Override
public boolean acceptsDocsOutOfOrder() {
return true;
}
public Set<Integer> getSet() {
return set;
}
};