2017-04-23 27 views
1

我是初学者到lucene。现在我因搜索问题而被阻止。我们正在开发一个API,将lucene用作我们应用程序的搜索引擎,并且必须在加入不同条件时进行大量查询。如何通过AND操作链接/连接多个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实体文档)。

但上述查询未能返回结果,因为附件,中间和域在不同的文档中。

有没有什么办法可以跨越多个文档?或者无论如何,我们可以加入像doc1.id = doc2.id这样的字段上的查询?

我要求大家提供建议或帮助解决此问题。它不建议

+0

有人可以帮忙吗? –

+0

您使用的是elasticsearch或原始Lucene API吗? –

+0

我只使用原始Lucene API。 –

回答

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,它具有所有文档类型组合的所有可搜索字段。

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包含索引字段名。

这里重要的是 - 子查询中的BooleanClause.Occur.MUST和主数据库中的Occur.SHOULD,这样您可以将子查询分组为一个主查询。

所以你会得到类似于 - (+sendr_name:sender1 + recip_name:recipient1 +subject:subject1) (+attachment:attachment1) ....等等。

上面会给你doc1 & doc2。

您可以删除以上示例代码中的助推部分(BoostQuery),并可以直接使用TermQuery

希望它有帮助,并让我知道我是否误解了您的要求。

+0

非常感谢萨比尔。它是非常详细和可理解的方式,你解释。我会根据你的尝试。到目前为止,我也跟你几乎一样。是的,我也只用Java开发,对不起,我没有提到。我会尽力回复。非常感谢。 –