Lucene问题searchinh连字符字段

时间:2017-02-20 16:05:58

标签: lucene lucene.net

我在Lucene遇到一些让我疯狂的问题。我有以下字段:

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,无论出于何种原因,它根本不起作用。

理想情况下,我们希望能够通过完整或部分目录编号搜索,例如“DF-”应该返回所有前缀为DF的项目

有谁知道我怎么做这个工作?

非常感谢

奥利

1 个答案:

答案 0 :(得分:0)

常见的问题来源是在索引时和查询时使用不同的分析器。您应该可以使用StandardAnalyzer获得良好的结果 - 它会将文字DF-GH5视为单个令牌,因此您可以使用fx df-gh5df-*进行搜索但请务必将其用于IndexWriterQueryParser

这是一个简单的示例,它使用单个文档构建内存索引,并尝试按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}");
    }
}