如何通过AND操作链接/连接多个Lucene文档

时间:2017-04-23 20:12:36

标签: search lucene

我是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这样的字段的查询?

我请求大家提供您的建议或帮助解决此问题。

1 个答案:

答案 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

希望它有所帮助,如果我误解了您的要求,请告诉我。