Lucene.NET“OR”

时间:2010-01-13 13:31:12

标签: lucene.net

如何在Lucene.NET中执行“OR”操作。基本上我所拥有的是一个ID数组,我想返回特定字段包含任何值的任何记录。我之前只使用一个值来执行此操作,但现在我想转换以下代码,以便MetaDataID是可能值的数组而不是单个值。

if (MetaDataID.Length > 0)
    completeQuery.Add(new QueryParser("MetaData", new StandardAnalyzer()).Parse(MetaDataID), BooleanClause.Occur.MUST);

4 个答案:

答案 0 :(得分:11)

将Lucene查询组合在一起时,如果您希望任何包含多个可能值中的任何一个的索引记录以及必须满足的其他条件,请创建多个布尔查询对象。

对于第一组“OR”条件:

BooleanQuery booleanQueryInner = new BooleanQuery();
Query query1 = new TermQuery(new Term("id", "<id 1>"));
Query query2 = new TermQuery(new Term("id", "<id 2>"));
Query query3 = new TermQuery(new Term("id", "<id 3>"));
Query query4 = new TermQuery(new Term("id", "<id 4>"));
booleanQueryInner.add(query1, BooleanClause.Occur.SHOULD);
booleanQueryInner.add(query2, BooleanClause.Occur.SHOULD);
booleanQueryInner.add(query3, BooleanClause.Occur.SHOULD);
booleanQueryInner.add(query4, BooleanClause.Occur.SHOULD);

现在与查询

中的其他条件结合使用
BooleanQuery booleanQueryOuter = new BooleanQuery();
booleanQueryOuter.add(booleanQueryInner, BooleanClause.Occur.MUST);
booleanQueryOuter.add(boolenaQueryOtherConditions, BooleanClause.Occur.MUST);

现在索引记录只有满足内部“OR”组中的一个条件并且满足“其他条件”查询中的条件时才会返回。

答案 1 :(得分:4)

您需要使用BooleanClause.Occur.SHOULD代替BooleanClause.Occur.MUST

e.g:

BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("id", "<id 1>"));
Query query2 = new TermQuery(new Term("id", "<id 2>"));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
booleanQuery.add(query2, BooleanClause.Occur.SHOULD);

答案 2 :(得分:3)

如果您真的想要解析查询,只需为查询选择正确的分析器和格式。

当您索引除英文全文以外的任何内容时,StandardAnalyzer不是一个好的选择,尤其不适合您的情况!它过滤了数字!

您遇到的最短解决方案是创建一个分析器,在分隔符处进行标记并将您的对象组合成一个字符串。

示例:

创建一个在典型分隔符和使用它的分析器中分割的Tokenizer

using System.IO;
using System.Linq;
using Lucene.Net.Analysis;

namespace Project.Analysis
{
    public class TermTokenizer : LetterTokenizer
    {
        // some static separators
        private static readonly char[] NONTOKEN_CHARS = new char[] { ',', ';', ' ', '\n', '\t' };

        protected override bool IsTokenChar(char c)
        {
            return !NONTOKEN_CHARS .Contains(c);
        }
    }

    public class LowerCaseTermAnalyzer : Analyzer
    {
        public override TokenStream TokenStream(string fieldName, TextReader reader)
        {
            return new LowerCaseFilter(new TermTokenizer(reader));
        }
    }
}

在解析器中使用新分析器

(您需要包含System.Linq)

if (MetaDataID.Length > 0)
{
    // the search term will look like this: "1;5;7"
    string searchTerm = string.Join(";", MetaDataID);

    // the query parser uses the new Analyzer
    QueryParser parser = new QueryParser("MetaData",new LowerCaseTermAnalyzer());

    // the parsed search term (only used internally) will look like this:
    // "MetaData:1 MetaData:5 MetaData:7", which is essentially what you want to achieve
    completeQuery.Add(new parser.Parse(MetaDataID), BooleanClause.Occur.MUST);
}

答案 3 :(得分:2)

使用BooleanQuery按id检索文档时要小心,因为它有最大布尔子句限制。

Lucene中的基本“OR”子句是这样执行的,假设您的可搜索字段名为“id”:

“id:1 id:2 id:3 id:4”

而不是“AND”查询:

“+ id:1 + id:2 + id:3 + id:4”

使用标准的QueryParser和StringBuilder应该为你带来魔力。