2013-06-05 105 views
0

我已經使用StandardAnalyzer創建了一個Lucene索引以及以下三個字段。Lucene.Net沒有給出任何結果,但盧克沒有給出結果

  1. StreetName
  2. 國家

我使用下面的包裝類,緩解了寫布爾查詢

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; 
    } 
} 

下面查詢不給我在Lucene的任何結果.Net但是當我在Luke中搜索相同的查詢時,它完美無缺地工作。

var query = new AndQuery(new QueryParam(city.ToLower(), "city"), new QueryParam(state.ToLower(), "state"), new QueryParam(streetAddress.ToLower(), "streetname")); 

執行query.GetQuery()給了我下面的結果查詢。

{+(城市:坦帕〜0.5)+(狀態:FL〜0.5)+(街道:網球場〜0.5)}

回答

1

您可以使用BooleanQuery進行搜索。用空格分割你的詞,然後在索引中創建查詢和搜索。

EX: -


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); 
    } 
} 
0

的問題是tennis court的治療。您沒有展示如何爲這些字段建立索引,但我會假設它們在索引中被標記,例如使用類似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)) 

這將找到一個匹配,因爲我們可以期望它找到city:tampastate:flstreet:tennis(見另一本Lucene的查詢分析器文檔section例子解釋查詢解析器的這種行爲)。它是否在默認字段中找到匹配court我不知道,但它並不真的需要。

A PhraseQuery是將多個術語(單詞)串在一起的典型方式,在Lucene Query中(這在解析查詢中看起來像street:"tennis court")。