Lucene.Net没有给出任何结果,但Luke给出了
我已经使用StandardAnalyzer创建了一个Lucene索引,其中包含以下三个字段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
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);
}
}