Lucene查询-“;精确匹配x、y、z中的一个“;

Lucene查询-“;精确匹配x、y、z中的一个“;,lucene,lucene.net,Lucene,Lucene.net,我有一个Lucene索引,它包含有一个“type”字段的文档,这个字段可以是“article”、“forum”或“blog”三个值之一。我希望用户能够在这些类型中搜索(每个文档类型都有一个复选框) 如何根据用户选择的类型创建Lucene查询? 几个先决条件是: 如果用户没有选择其中一种类型,我希望从该类型中得到no结果 限制类型字段不应影响结果的顺序 作为参考,如果我要用SQL写这篇文章(用于“博客或论坛搜索”),我会写: SELECT * FROM Docs WHERE [type] in

我有一个Lucene索引,它包含有一个“type”字段的文档,这个字段可以是“article”、“forum”或“blog”三个值之一。我希望用户能够在这些类型中搜索(每个文档类型都有一个复选框)

如何根据用户选择的类型创建Lucene查询?

几个先决条件是:

  • 如果用户没有选择其中一种类型,我希望从该类型中得到no结果
  • 限制类型字段不应影响结果的顺序
作为参考,如果我要用SQL写这篇文章(用于“博客或论坛搜索”),我会写:

SELECT * FROM Docs
WHERE [type] in ('blog', 'forum')

添加约束以拒绝未选择的文档。例如,如果只选中了“article”,则约束将为

-(type:forum type:blog)

虽然erickson的建议看起来不错,但您可以使用一个积极的约束条件和搜索词,例如
text:foo和type:article
,对于只选中“article”的案例,
或者
text:foo和(type:article或type:forum)
对于该案例,同时检查了“article”和“forum”。

作为参考,如果其他人遇到此问题,以下是我的解决方案:

IList<string> ALL_TYPES = new[] { "article", "blog", "forum" };
string q = ...; // The user's search string
IList<string> includeTypes = ...; // List of types to include
Query searchQuery = parser.Parse(q);
Query parentQuery = new BooleanQuery();
parentQuery.Add(searchQuery, BooleanClause.Occur.SHOULD);
// Invert the logic, exclude the other types
foreach (var type in ALL_TYPES.Except(includeTypes))
{
    query.Add(
        new TermQuery(new Term("type", type)),
        BooleanClause.Occur.MUST_NOT
    );
}
searchQuery = parentQuery;
IList ALL_TYPES=new[]{“文章”、“博客”、“论坛”};
字符串q=…;//用户的搜索字符串
IList includeTypes=…;//要包括的类型列表
querysearchquery=parser.Parse(q);
Query parentQuery=new BooleanQuery();
parentQuery.Add(searchQuery,BooleanClause.occurrent.SHOULD);
//反转逻辑,排除其他类型
foreach(除(包括类型)之外的所有类型中的变量类型)
{
查询.添加(
新术语查询(新术语(“类型”,类型)),
BooleanClause.occurrent.MUST\u不得
);
}
searchQuery=parentQuery;

我颠倒了逻辑(即排除了用户没有选择的类型),因为如果不这样做,结果的顺序就会丢失。我不知道为什么。。。!这是一种耻辱,因为它使代码不那么清晰/不可维护,但至少它可以工作

有趣的是,两个查询“text:foo和(type:article或type:forum)”和“text:foo和-type:blog”没有给出相同的结果,第一个查询首先返回blogs,而第二个查询则保持顺序(即blogs和article是混合的)。知道为什么吗?Lucene没有“AND”操作符。它有+(要求)和-(禁止)运算符。@erickson:我不同意:例如,这就是我最后所做的,虽然我使用了API而不是将其创建为字符串,但如果您感兴趣,请参阅我的答案。