2013-05-09 86 views
1

我目前正在尝试在Lucene中完成一些全文查询。我想实现如下:Lucene查询解析器

当越来越像

搜索词语“你好,世界”

我想一个查询,搜索在所有领域两个术语。然而,这两个术语不一定只发生在一个领域,而必须发生在所有领域。

因此,结果应该是这样的:

+(字段1:你好场2:你好)+(字段1:世界字段2:世界)

当使用MultiFieldQueryParser我只得到以下:

(+字段1:你好+字段1:世界)(+场2:你好+字段2:世界)

据我所知,这需要每个术语只发生在一个领域。

有没有机会使用默认的Lucene功能来实现这样的行为,还是我必须实现我自己的查询分析器?

我目前的做法是将域对象上的所有字段内容连接在一个字段中,只查询那一个。然而,这种方法是很丑陋......

感谢, 马蒂亚斯

回答

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模式元素查看Solr文档,其中他们使用recommend this pattern


如果你真的想使用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); 

但将与突破查询了复杂性,如果是用户输入,则自动处理。再次,我会坚持你现在正在做的。

+0

很好的答案,谢谢!我会坚持使用复合字段,但必须将商店属性设置为“否”。你是对的 - 最好是直接计算财产......谢谢! – user1050133 2013-05-09 17:32:31