簡體   English   中英

Lucene .NET搜索結果

[英]Lucene .NET search results

我正在使用此代碼進行索引:

public void IndexEmployees(IEnumerable<Employee> employees)
{
    var indexPath = GetIndexPath();
    var directory = FSDirectory.Open(indexPath);

    var indexWriter = new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);

    foreach (var employee in employees)
    {
        var document = new Document();
        document.Add(new Field("EmployeeId", employee.EmployeeId.ToString(), Field.Store.YES, Field.Index.NO, Field.TermVector.NO));
        document.Add(new Field("Name", employee.FirstName + " " + employee.LastName, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
        document.Add(new Field("OfficeName", employee.OfficeName, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
        document.Add(new Field("CompetenceRatings", string.Join(" ", employee.CompetenceRatings.Select(cr => cr.Name)), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));

        indexWriter.AddDocument(document);
    }

    indexWriter.Optimize();
    indexWriter.Close();

    var indexReader = IndexReader.Open(directory, true);
    var spell = new SpellChecker.Net.Search.Spell.SpellChecker(directory);
    spell.ClearIndex();

    spell.IndexDictionary(new LuceneDictionary(indexReader, "Name"));
    spell.IndexDictionary(new LuceneDictionary(indexReader, "OfficeName"));
    spell.IndexDictionary(new LuceneDictionary(indexReader, "CompetenceRatings"));
}

public DirectoryInfo GetIndexPath()
{
    return new DirectoryInfo(HttpContext.Current.Server.MapPath("/App_Data/EmployeeIndex/"));
}

並且此代碼可以找到結果(以及建議):

public SearchResult Search(DirectoryInfo indexPath, string[] searchFields, string searchQuery)
{
    var directory = FSDirectory.Open(indexPath);

    var standardAnalyzer = new StandardAnalyzer(Version.LUCENE_29);

    var indexReader = IndexReader.Open(directory, true);
    var indexSearcher = new IndexSearcher(indexReader);

    var parser = new MultiFieldQueryParser(Version.LUCENE_29, searchFields, standardAnalyzer);
    //parser.SetDefaultOperator(QueryParser.Operator.OR);
    var query = parser.Parse(searchQuery);

    var hits = indexSearcher.Search(query, null, 5000);

    return new SearchResult
                {
                    Suggestions = FindSuggestions(indexPath, searchQuery),
                    LuceneDocuments = hits
                        .scoreDocs
                        .Select(scoreDoc => indexSearcher.Doc(scoreDoc.doc))
                        .ToArray()
                };
}

public string[] FindSuggestions(DirectoryInfo indexPath, string searchQuery)
{
    var directory = FSDirectory.Open(indexPath);

    var spell = new SpellChecker.Net.Search.Spell.SpellChecker(directory);

    var similarWords = spell.SuggestSimilar(searchQuery, 20);

    return similarWords;
}

var searchResult = Search(GetIndexPath(), new[] { "Name", "OfficeName", "CompetenceRatings" }, "admin*");

簡單的查詢,例如:admin或admin *不會給我任何結果。 我知道有一名員工有這個名字。 如果我尋找詹姆斯,我希望能找到詹姆斯詹姆森。

謝謝!

第一件事。 您必須將更改提交到索引。

indexWriter.Optimize();
indexWriter.Commit(); //Add This
indexWriter.Close();

編輯#2另外,保持簡單直到你得到一些有用的東西。

評論這些東西。

//var indexReader = IndexReader.Open(directory, true);
//var spell = new SpellChecker.Net.Search.Spell.SpellChecker(directory);
//spell.ClearIndex();

//spell.IndexDictionary(new LuceneDictionary(indexReader, "Name"));
//spell.IndexDictionary(new LuceneDictionary(indexReader, "OfficeName"));
//spell.IndexDictionary(new LuceneDictionary(indexReader, "CompetenceRatings"));

編輯#3

您正在搜索的字段可能不會經常更改。 我會將它們包含在您的搜索功能中。

string[] fields = new string[] { "Name", "OfficeName", "CompetenceRatings" };

我建議這個的最大原因是Fields是區分大小寫的,有時你不會得到任何結果,這是因為你搜索“name”字段(不存在)而不是“Name”字段。 更容易以這種方式發現錯誤。

在與Lucene合作的(有限)經驗中,我發現你必須建立自己的查詢才能獲得“谷歌”般的行為。 這是我做的,YMMV,但它在我的應用程序中生成預期的結果。 基本思想是組合術語查詢(完全匹配),前綴查詢(以術語開頭的任何內容),以及搜索字符串中每個術語的模糊查詢。 下面的代碼不會編譯,但會給你一個想法

Query GetQuery(string querystring)
{

   Search.Search.BooleanQuery query = new Search.Search.BooleanQuery();

   Search.Analysis.TokenStream tk = StandardAnalyzerInstance.TokenStream(null, new StringReader(querystring));
   Search.Analysis.Tokenattributes.TermAttribute ta = tk.GetAttribute(typeof(Search.Analysis.Tokenattributes.TermAttribute)) as Search.Analysis.Tokenattributes.TermAttribute;

    while (tk.IncrementToken())
    {
         string term = ta.Term();
         Search.Search.BooleanQuery bq = new Search.Search.BooleanQuery();
         bq.Add(new Search.Search.TermQuery(new Search.Index.Term("fieldToQuery", term)), Search.Search.BooleanClause.Occur.SHOULD);
         bq.Add(new Search.Search.PrefixQuery(new Search.Index.Term("fieldToQuery", term)), Search.Search.BooleanClause.Occur.SHOULD);
         bq.Add(new Search.Search.FuzzyQuery(new Search.Index.Term("fieldToQuery", term)), Search.Search.BooleanClause.Occur.SHOULD);
         query.Add(bq, Search.Search.BooleanClause.Occur.MUST);
    }

    return query;
}

Parse()方法是繼承的。 您是否嘗試過使用返回Query對象的靜態方法?

Parse(Version matchVersion, String[] queries, String[] fields, Analyzer analyzer)

暫無
暫無

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

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