簡體   English   中英

C#中的Lucene查詢找不到標點符號的結果

[英]Lucene query in C# not finding results with punctuation

我有一個搜索欄,可在“說明”字段上執行lucene查詢,但帶有撇號時不會返回結果。 例如,我有一個描述為Herter's® EZ-Load 200lb Feeder - 99018 當我搜索“ Herter”時,會得到結果,但是如果搜索“ Herter's”或“ Herters”,則不會得到結果。 這是我的搜索代碼:

var query = Request.QueryString["q"];
var search = HttpContext.Current.Server.UrlDecode(query);

var rewardProductLookup = new RewardCatalogDataHelper();
RewardProductSearchCriteria criteria = new RewardProductSearchCriteria()
{
    keywords = search,
    pageSize = 1000,
    sortDirection = "desc"
};

IEnumerable<SkinnyItem> foundProducts = rewardProductLookup.FindByKeywordQuery(criteria);

public IEnumerable<SkinnyItem> FindByKeywordQuery(RewardProductSearchCriteria query)
{
    var luceneIndexDataContext = new LuceneDataContext("rewardproducts", _dbName);
    string fieldToQuery = "rpdescription";
    bool sortDirection = query.sortDirection.ToLower().Equals("desc");

    MultiPhraseQuery multiPhraseQuery = new MultiPhraseQuery();
    var keywords = query.keywords.ToLower().Split(',');
    foreach (var keyword in keywords)
    {
        if (!String.IsNullOrEmpty(keyword))
        {
            var term = new Term(fieldToQuery, keyword);
            multiPhraseQuery.Add(term);
        }
    }

    var booleanQuery = new BooleanQuery();
    booleanQuery.Add(multiPhraseQuery, BooleanClause.Occur.MUST);

    return
        luceneIndexDataContext.BooleanQuerySearch(booleanQuery, fieldToQuery, sortDirection)
            .Where(i => i.Fields["eligibleforpurchase"] == "1");
}

這里的問題是分析。 您尚未指定在這種情況下使用的分析器,因此我假設它是StandardAnalyzer

經過分析,術語“ Herter's”將翻譯為“ herter”。 但是,您的FindByKeywordQuery方法中沒有應用分析器,因此查找“ herter”有效,但“ herter's”無效。

一種解決方案是使用QueryParser ,而不是手動構造MultiPhraseQuery QueryParser將處理標記化,小寫等。 就像是:

QueryParser parser = new QueryParser(VERSION, "text", new StandardAnalyzer(VERSION));
Query query = parser.Parse("\"" + query.keywords + "\"");

單引號是查詢中文本字段的分隔符。

Select * FROM Product where Description = 'foo' 

您將需要對查詢的任何單引號進行轉義或加倍。 嘗試循環。

foreach (var keyword in keywords)
{
    if (!String.IsNullOrEmpty(keyword))
    {
        var term = new Term(fieldToQuery, keyword);
        term = term.Replace("'", "''");
        multiPhraseQuery.Add(term);
    }
}

您還可以創建擴展方法

    [DebuggerStepThrough]
    public static string SanitizeSQL(this string value)
    {
        return value.Replace("'", "''").Replace("\\", "\\\\");
    }

在這種情況下,您可以在循環中執行此操作

foreach (var keyword in keywords)
{
    if (!String.IsNullOrEmpty(keyword))
    {
        var term = new Term(fieldToQuery, keyword.SanitizeSQL());
        multiPhraseQuery.Add(term);
    }
}

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM