2017-02-20 25 views
0

У меня проблемы с Lucene, которые сводят меня с ума. У меня есть следующие поля:Проблемы с Lucene searchinh с дефисным полем

doc.Add(new Field("cataloguenumber", i.CatalogueNumber.ToLower(), Field.Store.YES, Field.Index.ANALYZED)); 

который будет содержать номер каталога, который выглядит примерно так:

  • DF-GH5
  • DF-FJ4
  • DF-DOG
  • AC -DP
  • AC-123
  • AC-DOCO

т. Е. Два символа, за которыми следует дефис, а затем 2-5 буквенно-цифровых символов.

Я пытаюсь запустить булево запрос, чтобы позволить пользователям осуществлять поиск по данным:

// specify the search fields, lucene search in multiple fields 
     string[] searchfields = new string[] { "cataloguenumber", "title", "author", "categories", "year", "length", "keyword", "description" }; 

     // Making a boolean query for searching and get the searched hits     
     BooleanQuery mainQuery = new BooleanQuery(); 
     QueryParser parser; 

     //Add filter for main keyword 
     parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, searchfields, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30)); 
     parser.AllowLeadingWildcard = true; 
     mainQuery.Add(parser.Parse(GetMainSearchQueryString(SearchPhrase)), Occur.MUST); 

Система работает нормально для всех полей КРОМЕ cataloguenumber, которые по каким-то причинам не работает вообще.

В идеале мы хотели бы иметь возможность поиска по полному или частичному cataloguenumber так, например, «DF-» должен вернуть все элементы с префиксами DF

Кто-нибудь знает, как я могу сделать эту работу?

Большое спасибо заранее

Olly

+0

Стоит добавить, что я знаю, что это поле индексируется (в той или иной форме), потому что я открыл файл _mcd.cfs и я могу увидеть некоторые каталожные номера там –

ответ

0

Обычным источником проблем является использование различных анализаторов на индекс времени и запросов времени. Вы должны иметь хорошие результаты, используя StandardAnalyzer - он обрабатывает текст DF-GH5 как единый токен, чтобы вы могли искать с помощью fx df-gh5 или df-*, но обязательно используйте его для IndexWriter и QueryParser.

Вот простой пример, который строит индекс в памяти с одним документом и пытается запросить индекс на cataloguenumber.

public static void Test() 
{ 
    // Use an in-memory index. 
    RAMDirectory indexDirectory = new RAMDirectory(); 

    // Make sure to use the same analyzer for indexing 
    Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30); 

    // Add single document to the index. 
    using (IndexWriter writer = new IndexWriter(indexDirectory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED)) 
    { 
     Document document = new Document(); 
     document.Add(new Field("content", "This is just some text", Field.Store.YES, Field.Index.ANALYZED)); 
     document.Add(new Field("cataloguenumber", "DF-GH5", Field.Store.YES, Field.Index.ANALYZED)); 

     writer.AddDocument(document); 
    } 

    var parser = new MultiFieldQueryParser(
     Lucene.Net.Util.Version.LUCENE_30, 
     new[] { "cataloguenumber", "content" }, 
     analyzer); 

    var searcher = new IndexSearcher(indexDirectory); 

    DoSearch("df-gh5", parser, searcher); 
    DoSearch("df-*", parser, searcher); 
} 

private static void DoSearch(string queryString, MultiFieldQueryParser parser, IndexSearcher searcher) 
{ 
    var query = parser.Parse(queryString); 

    TopDocs docs = searcher.Search(query, 10); 

    foreach (ScoreDoc scoreDoc in docs.ScoreDocs) 
    { 
     Document searchHit = searcher.Doc(scoreDoc.Doc); 
     string cataloguenumber = searchHit.GetValues("cataloguenumber").FirstOrDefault(); 
     string content = searchHit.GetValues("content").FirstOrDefault(); 
     Console.WriteLine($"Found object: {cataloguenumber} {content}"); 
    } 
} 
+0

Работа как шарм !! Спасибо огромное! –