[英]Nesting searches in Lucene without duplicating keywords
我想使用以下逻辑在Lucene(实际上是Lucene.NET,但是我可以根据需要从Java转换)中进行搜索:
(field1:A field1:B field1:C)
) (+(field1:A) +(field2:B field2:C))
) 目前,我的代码可以测试给定的搜索是否不产生结果,并将所有确实产生结果的结果与在一起。 但是我没有办法在针对每个字段进行测试之前停止它(这不必要地限制了结果)-当前它以如下查询结束: (+(field1:A field1:B field1:C) +(field3:A field3:B field3:C))
当我希望它是(+(field1:A field1:C) +(field3:B))
。 我不能只看第一次搜索的结果并从搜索字符串中删除单词,因为分析器在解析单词以进行搜索时会对其进行修饰,并且我无法解开它们以找出原始单词中的哪个它所对应的搜索词。
有什么建议么?
编辑:好的,通常我更喜欢抽象地描述我的问题,但是我认为其中的一部分会在过程中迷失,所以我会更具体。
我正在为一个需要具有多层搜索逻辑的站点构建搜索引擎。 我将跟踪的一些示例搜索为:
索引包含具有七个字段的文档-与本示例相关的文档是:
通常,搜索的每个步骤的逻辑如下:
每个步骤都类似于:
因此,这三个示例搜索应如何显示:
+path:headphones +datatype:Category
path:headphones
和datatype:Category
,使“ Monster”不匹配 +path:headphones +brand:monster
path:headphones
和brand:monster
匹配项,原始查询中没有剩下任何单词,因此我们退回Monster的所有耳机。 +(path:monster path:headphones path:white) +datatype:Category
path:headphones
和datatype:Category
匹配项,从而使“ White”和“ Monster”不匹配 +path:headphones +(brand:monster +brand:white)
path:headphones
和brand:monster
,使“白色”无与伦比 +path:headphones +brand:monster +keywords:white
+(path:foobar path:headphones path:white) +datatype:Category
path:headphones
和datatype:Category
,使“ White”和“ Foobar”不匹配 +path:headphones +(brand:foobar +brand:white)
+path:headphones +(keywords:white keywords:foobar)
path:headphones
和keywords:white
,使“ Foobar”不匹配 我有两个问题:
+path:headphones +(brand:headphones brand:monster)
)。 +path:headphon +datatype:Taxonomy
因为我正在处理它以进行搜索。 因此,我不能采用匹配的术语并将其从原始查询中删除(因为“ headphon”!=“ headphones”)。 希望这可以使我正在寻找的内容更加清楚。
我不了解您的用例,但您听起来好像在询问BooleanQuery API。 您可以通过调用getClauses
来获取查询的子句。
一个简单的例子:
BooleanQuery bq = new BooleanQuery();
bq.add(new TermQuery(new Term("field1","a")), BooleanClause.Occur.SHOULD)
bq.add(new TermQuery(new Term("field1","b")), BooleanClause.Occur.SHOULD)
BooleanClause[] clauses = bq.getClauses();
编辑:也许您只是在要求搜索算法。 用伪代码:
generate_query (qs_that_matched, qs_that_didnt_match, level):
new_query = qs_that_matched AND level:qs_that_didnt_match
qs_still_unmatched = ...
qs_which_just_matched = ...
if qs_still_unmatched != null:
return generate_query(qs_that_matched AND qs_which_just_matched, qs_still_unmatched, level+1)
else:
return qs_that_matched AND qs_which_just_matched
最后,我构建了一个QueryTree类,并将查询存储在树形结构中。 它存储对一个查询的函数的引用,要插入该查询的术语列表,是否应该对这些术语进行“与”或“或”运算,以及一个子项列表(代表匹配项的唯一组合)。
要执行下一级别的搜索,我只需在树中最深的节点上调用Evaluate(Func<string, QueryParser.Operator, Query> newQuery)
,并引用一个接受带有条件和运算符并返回正确查询的函数对于那套逻辑。 然后, Evaluate
函数根据传递给它的不匹配项列表和所有祖先查询的结果集(通过与父项进行AND运算,与父项进行AND运算,依此类推)来测试该新查询。 然后,它使用GetHitTerms为每组匹配项创建子项,并将未匹配的项提供给子项。 对每个搜索级别重复此步骤。
我怀疑有更好的方法可以做到这一点-我什至没有研究Xodarap提到的Bobo,而且我从没真正遇到过搜索工作(按照丹尼斯的说法)。 但是,它正在工作,这意味着该是该网站其他内容的时候了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.