Lucene.Net没有给出任何结果,但Luke给出了

Lucene.Net没有给出任何结果,但Luke给出了,lucene,lucene.net,Lucene,Lucene.net,我已经使用StandardAnalyzer创建了一个Lucene索引,其中包含以下三个字段 街道名称 城市 陈述 我使用下面的包装器类来简化布尔查询的编写 public interface IQuery { BooleanQuery GetQuery(); } public class QueryParam : IQuery { public string[] Fields { get; set; } public string Term { ge

我已经使用StandardAnalyzer创建了一个Lucene索引,其中包含以下三个字段

  • 街道名称
  • 城市
  • 陈述
  • 我使用下面的包装器类来简化布尔查询的编写

    public interface IQuery
        {
            BooleanQuery GetQuery();
        }
    public class QueryParam : IQuery
    {
        public string[] Fields { get; set; }
        public string Term { get; set; }        
        private BooleanQuery _indexerQuery;                    
        public QueryParam(string term, params string[] fields)
        {
            Term = term;
            Fields = fields;
        }        
        public BooleanQuery GetQuery()
        {
            _indexerQuery = new BooleanQuery();
            foreach (var field in Fields)
                _indexerQuery.Add(new FuzzyQuery(new Term(field, Term)), Occur.SHOULD);
            return _indexerQuery;
        }
    }
    public class AndQuery : IQuery
    {
        private readonly IList<IQuery> _queryParams = new List<IQuery>();        
        private BooleanQuery _indexerQuery;
        public AndQuery(params IQuery[] queryParams)
        {
            foreach (var queryParam in queryParams)
            {
                _queryParams.Add(queryParam);
            }
        }    
        public BooleanQuery GetQuery()
        {
            _indexerQuery = new BooleanQuery();
            foreach (var query in _queryParams)
                _indexerQuery.Add(query.GetQuery(), Occur.MUST);
            return _indexerQuery;
        }
    }
    public class OrQuery : IQuery
    {
        private readonly IList<IQuery> _queryParams = new List<IQuery>();
        private readonly BooleanQuery _indexerQuery = new BooleanQuery();
        public OrQuery(params IQuery[] queryParams)
        {
            foreach (var queryParam in queryParams)
            {
                _queryParams.Add(queryParam);
            }
        }
        public BooleanQuery GetQuery()
        {
            foreach (var query in _queryParams)
                _indexerQuery.Add(query.GetQuery(), Occur.SHOULD);
            return _indexerQuery;
        }
        public OrQuery AddQuery(IQuery query)
        {
            _queryParams.Add(query);
            return this;
        }
    }
    
    执行
    query.GetQuery()
    将给出下面的结果查询


    {+(城市:坦帕~0.5)+(州:fl~0.5)+(街道:网球场~0.5)}

    问题在于网球场的处理。您还没有展示如何为这些字段编制索引,但我将假设它们在索引中被标记,例如使用
    StandardAnalyzer
    。这意味着,“网球场”将分为两个单独的术语“网球”和“球场”。但是,当手动创建FuzzyQuery时,没有分析或标记化,因此您只有一个术语“网球场”。“网球场”和“网球”(6次编辑)或“球场”(7次编辑)之间的编辑距离很大,因此两者都不匹配

    这里的一个困惑似乎是

    +(city:tampa~0.5) +(state:fl~0.5) +(street:tennis court~0.5)
    
    似乎有效。但是,假设用于调试的文本查询输出可以通过queryparser运行以生成相同的查询是不安全的,这是一个很好的示例。
    QueryParser
    语法无法表达您可以对手动构造的查询执行的所有操作。通过查询解析器运行该查询将生成一个更像以下内容的查询:

    +(city:tampa~0.5) +(state:fl~0.5) +((street:tennis) (defaultField:court~0.5))
    
    它将找到一个匹配项,因为我们可以期望它找到
    城市:坦帕
    州:佛罗里达
    ,和
    街道:网球
    (有关解释查询解析器行为的另一个示例,请参阅此Lucene查询解析器文档)。我不知道它是否在默认字段的
    court
    上找到匹配项,但它实际上并不需要


    A是在Lucene查询中将多个术语(单词)串在一起的典型方式(在解析的查询中,这看起来像
    街道:“网球场”

    您可以使用BooleanQuery进行搜索。用空格分段分隔术语,然后创建查询并在索引中搜索

    例:-


    +(city:tampa~0.5) +(state:fl~0.5) +((street:tennis) (defaultField:court~0.5))
    
    BooleanQuery booleanQuery = new BooleanQuery()
    BooleanQuery searchTermQuery = new BooleanQuery();
    foreach (var searchTerm in searchTerms)
    {
        var searchTermSegments = searchTerm.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        if (searchTermSegments.Count() > 1)
        {
            searchTermQuery.Clauses().Clear();
            foreach (var SegTex in searchTermSegments)
            {
                searchTermQuery.Add( new FuzzyQuery(new Term("FieldName", SegTex.ToLower().Trim())),BooleanClause.Occur.MUST);
            }
            booleanQuery.Add(searchTermQuery, BooleanClause.Occur.MUST);
        }
        else
        {
            booleanQuery.Add(new FuzzyQuery(new Term("FieldName", searchTerm.ToLower().Trim())), BooleanClause.Occur.MUST);
        }
    }