我目前正在尝试在Lucene中完成一些全文查询。我想要实现的目标如下:
获得类似
的搜索字词“你好和世界”
我想要一个在所有字段中搜索这两个字词的查询。但是,这两个术语不一定只出现在一个字段中,而是必须出现在所有字段中。
因此,结果应如下所示:
+(field1:hello field2:hello)+(field1:world field2:world)
使用MultiFieldQueryParser时,我只能得到以下内容:
(+ field1:hello + field1:world)(+ field2:hello + field2:world)
据我所知,这要求每个术语只在一个领域发生。
有没有机会使用默认的Lucene功能实现这样的行为,还是我必须实现自己的查询解析器?
我目前的方法是仅在一个字段中连接域对象上的所有字段内容,并仅查询该字段。但是,这种方法非常难看......
谢谢, 的Matthias
答案 0 :(得分:0)
我绝对不同意你目前的做法很难看。我发现将所有内容收集到所有内容字段中是启用随处搜索搜索的最简洁方法。
但是,如果您手动连接字段,那可能会有点混乱。相反,您可以添加多个具有相同名称的字段,这些字段将在索引中有效连接。类似的东西:
//Don't actually construct your fields this way.
//Just cutting out some of the boilerplate for simplicity.
document.add(new Field("field1", firstvalue));
document.add(new Field("everything", firstvalue));
document.add(new Field("field2", nextvalue));
document.add(new Field("everything", nextvalue));
可以很好地将它全部放入同一个领域。通常,只要没有存储“所有”字段(当然不应该存储),这对索引大小的影响应该很小,并且应该表现良好。我之前刚刚创建了一个实用程序调用,它将字段添加到文档中,并将其透明地添加到“所有”或“所有”字段中以用于索引的任何内容。
在这种情况下,通过使用copyField
架构元素,查看他们recommend this pattern所在的Solr文档。
如果你真的想使用MultiFieldQueryParser
,你可能需要单独解析子查询,并用booleanQuery连接它们,如:
BooleanQuery bq = new BooleanQuery();
bq.add(new BooleanClause(multifieldQP.parse("hello"), BooleanClause.Occur.MUST));
bq.add(new BooleanClause(multifieldQP.parse("world"), BooleanClause.Occur.MUST));
searcher.search(bq);
但是如果用户输入了查询,那么打破查询就会很复杂,无法自动处理。再一次,我坚持你现在正在做的事情。