如何有效地将BooleanQuery中的Term数组与Lucene.Net相结合?

时间:2013-10-16 10:54:42

标签: lucene lucene.net

我需要建议如何编写一个有效的查询,使用BooleanQuery(或其他更有效的方式)从Lucene索引中删除文档 - 查询应该将多个条款与Guid值组合在一起(通过“Guid”字段删除文档)以及“版本”字段..

索引可能包含“Guid”字段中具有相同值的文档,但“Version”字段中的值不同。

以下是我的功能:

private void RemoveFromIndex(string[] guids, IndexWriter writer)
        {
            var terms = guids.Select(guid => new Term("Guid", guid)).ToArray();

            if (!isGlobalIndex)
            {
                writer.DeleteDocuments(terms); //This is working perfectly
            }
            else
            {
                //Delete items but only of the corresponding version
                BooleanQuery bQ = new BooleanQuery();

                if (!string.IsNullOrEmpty(repository.versionName))
                {
                    bQ.Add(new TermQuery(new Term("Version", repository.versionName)), Occur.MUST);
                }

            //Is there a more efficient way of doing it?
            foreach (var term in terms) {
                bQ.Add(new TermQuery(term), Occur.SHOULD);
            }

                writer.DeleteDocuments(bQ);
            }
        }

1 个答案:

答案 0 :(得分:2)

不,这是实现你所描述的最有效的方法。对于代码的第二部分(向外“else”子句),Lucene查询将类似于:

+GUID:someGuidValue version:v1 version:v2 version:v3

您可以打印查询对象(或调试它)以确认它确实是它为您创建的Lucene查询。如果是的话,那真的是最简单的方法。

==根据评论更新:==

首先,我不太确定您使用的Lucene API。我大多熟悉Java API。在Java API中,您可以在布尔查询中configure the max boolean clauses,如下所示:

BooleanQuery bq = new BooleanQuery();
bq.setMaxClauseCount(3000);

这可以帮助您避免在while循环中移动查询。

此外,就多项查询而言,还有一个基础(抽象)MultiTermQuery类,以及它的一些实际实现,例如:FuzzyQuery,NumericRangeQueriy,RegexQuery等。这些用于更专业/异国情调涉及多个术语的查询。对于简单的查询条件,例如这些,BooleanQuery工作正常。