我是lucene的初学者。现在因为搜索问题我被阻止了。我们正在开发一个API,使用lucene作为我们应用程序的搜索引擎,并且必须在加入时使用不同条件进行大量查询。
我们将许多实体存储到lucene中作为单独的文档。
每个实体都以记录数量的形式出现,并作为单独的文档存储到lucene中。下面添加了数据的示例结构,
序列号1 - > 16是lucene的文档。
1) "id": "1","sendr_name": "**sender1**", "recip_name": "**recipient1**", "subject": "**subject1**"
2) "id": "1","attachment": "**attachment1**"
3) "id": "1","domain": "**domain1**", "ip": "ip1"
5) "id": "1","mid": "**mid1**"
6) "id": "1","type": "type1"
7) "id": "2","sendr_name": "sender1", "recip_name": "recipient1", "subject": "subject1"
8) "id": "2","attachment": "attachment2"
9) "id": "2","domain": "domain1", "ip": "ip2"
10) "id": "2","mid": "mid2"
11) "id": "2","type": "type2"
12) "id": "3","sendr_name": "sender1", "recip_name": "recipient3", "subject": "subject3"
13) "id": "3","attachment": "attachment3"
14) "id": "3","domain": "domain1", "ip": "ip3"
15) "id": "3","mid": "mid3"
16) "id": "3","type": "type3"
注意:序列号。 1-16是不同实体和字段的文档" id "在内部生成,因此id值不能被用户用作查询值。
我需要在特定条件下提取特定实体。
+sendr_name:sender1 + recip_name:recipient1 +subject:subject1 +attachment:attachment1 +domain:domain1 +mid:mid1
这是获取实体信息(实体的1-6个文档)。
但是上面的查询无法返回结果,因为附件,mid和域在不同的docs中。
我们有什么方法可以跨越并调整多个文档吗?或者无论如何我们可以加入像doc1.id = doc2.id这样的字段的查询?
我请求大家提供您的建议或帮助解决此问题。
答案 0 :(得分:0)
首先,使用简单的Lucene,不建议将异构文档存储在同一索引中,因为长期运行和其他基础结构问题可能存在许多其他问题。
完成此SO Answer。您最好使用其他顶级技术,如SOLR或ElasticSearch,以便更好地处理您描述的场景。
您没有显示任何代码,因此如果您使用的是Java或.NET或Lucene API版本,则不清楚。
我正在使用Lucene 6.0和Java,我认为它可以用 - BooleanQuery作为顶级容器来实现。
public static BooleanQuery.Builder buildQuery(final SearchBean searchBean) {
BooleanQuery.Builder finalQuery = new BooleanQuery.Builder();
finalQuery.add(buildDoc1Query(searchBean).build(), Occur.SHOULD);
finalQuery.add(buildDoc2Query(searchBean).build(), Occur.SHOULD);
....
....
return finalQuery;
}
即。首先,根据所有需要搜索的内容,为每个实体类型构建查询。 SearchBean
是一个POJO,它包含所有doc类型的所有可搜索字段。
private static BooleanQuery.Builder buildDoc1Query(SearchBean searchBean ) {
BooleanQuery.Builder doc1MatchQuery = new BooleanQuery.Builder();
if (StringUtils.isNotEmpty(searchBean.getSender_name())) {
doc2MatchQuery.add(new BoostQuery(new TermQuery(new Term(AppConstants.SENDER_NAME, searchBean.getSender_name())), MatchingBooster.SENDER_NAME), BooleanClause.Occur.MUST);
}
if (StringUtils.isNotEmpty(searchBean.getRecip_name())) {
doc2MatchQuery.add(new BoostQuery(new TermQuery(new Term(AppConstants.RECIP_NAME, searchBean.getRecip_name()())), MatchingBooster.RECIP_NAME), BooleanClause.Occur.MUST);
}
....
....
return doc2MatchQuery;
}
StringUtils
来自Apache Commons库。
AppConstants
包含索引字段名称。
这里重要的是 - {child}查询中的BooleanClause.Occur.MUST
和master中的Occur.SHOULD
,这样您就可以将子查询分组到一个主查询中。
所以你会得到像(+sendr_name:sender1 + recip_name:recipient1 +subject:subject1) (+attachment:attachment1) ....
这样的东西。
上面会给你doc1& DOC2。
您可以删除以上示例代码(BoostQuery
)中的提升部分,并可以直接使用TermQuery
。
希望它有所帮助,如果我误解了您的要求,请告诉我。