我有一个Lucene索引,其中包含具有“type”字段的文档,该字段可以是“article”,“forum”或“blog”三个值之一。我希望用户能够在这些类型中进行搜索(每个文档类型都有一个复选框)
如何根据用户选择的类型创建Lucene查询?
一些先决条件是:
如果我在SQL中写这个(用于“博客或论坛搜索”),我可以写一下:
SELECT * FROM Docs
WHERE [type] in ('blog', 'forum')
答案 0 :(得分:4)
作为参考,如果其他人遇到这个问题,这是我的解决方案:
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;
我颠倒了逻辑(即排除了用户未选择的类型),因为如果不这样做,结果的排序就会丢失。我不确定为什么......!遗憾的是它使代码不那么清晰/可维护,但至少它有效!
答案 1 :(得分:3)
添加约束以拒绝未选择的文档。例如,如果仅选中“article”,则约束为
-(type:forum type:blog)
答案 2 :(得分:0)
虽然erickson的建议看起来很好,但你可以使用一个肯定的约束ANDed和你的搜索词,例如text:foo AND type:article
只检查案例“article”,
或者text:foo AND (type:article OR type:forum)
对于案件“物品”和“论坛”都进行了检查。