简体   繁体   English

Lucene.net:使用 MultiFieldQueryParser 时没有搜索结果

[英]Lucene.net: No search results when using MultiFieldQueryParser

I am using Lucene.Net version 4.8.0 with .NET Core 3.1.我正在使用Lucene.Net 4.8.0版和 .NET Core 3.1。 In the sample code below, I write a new index and add three documents to it.在下面的示例代码中,我编写了一个新索引并向其中添加了三个文档。 Each document contains the fields ProjectName , Customer and Country .每个文档都包含ProjectNameCustomerCountry字段。

When I parse the query "Germany" , the search returns 2 hits for documents that contain the word "Germany" in any of its fields.当我解析查询"Germany"时,搜索返回 2 个命中,以查找在其任何字段中包含单词 "Germany" 的文档。 However, when I parse the query "Country:Germany" , the search returns 0 hits, although there clearly is a document with the value "Germany" in its Country field.但是,当我解析查询"Country:Germany"时,搜索返回 0 个命中,尽管其Country字段中显然有一个值为 "Germany" 的文档。

What am I doing wrong?我究竟做错了什么?

I also checked my index by means of the Luke tool ( https://github.com/DmitryKey/luke/releases/tag/4.8.0 ).我还通过 Luke 工具( https://github.com/DmitryKey/luke/releases/tag/4.8.0 )检查了我的索引。 With Luke, the search works fine for the same index directory.使用 Luke,搜索对于相同的索引目录工作正常。

My C# code is here:我的 C# 代码在这里:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using Directory = System.IO.Directory;

namespace LuceneTestApp
{
    class Program
    {
        static string CreateTestIndex()
        {
            string indexDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            if(Directory.Exists(indexDir))
                throw new IOException("Random index directory already exists. Please try again.");

            using var dir = FSDirectory.Open(indexDir);
            using var analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48);
            var indexConfig = new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer);
            using var writer = new IndexWriter(dir, indexConfig);

            AddDocumentTo(writer, "AwesomeProject_1", "Volkswagen", "Germany");
            AddDocumentTo(writer, "AwesomeProject_2", "Ford", "USA");
            AddDocumentTo(writer, "AwesomeProject_3", "Audi Germany", "France");

            writer.Commit();
            return indexDir;
        }

        static void AddDocumentTo(IndexWriter writer, string projectName, string customer, string country)
        {
            var doc = new Document();
            doc.Add(new StringField( "ProjectName", projectName, Field.Store.YES));
            doc.Add(new TextField(   "Customer",    customer,    Field.Store.YES));
            doc.Add(new TextField(   "Country",     country,     Field.Store.YES));
            writer.AddDocument(doc);
        }

        static IList<string> Search(string indexDir, string queryString)
        {
            using var dir = FSDirectory.Open(indexDir);
            using var reader = DirectoryReader.Open(dir);
            using var analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48);
            var searcher = new IndexSearcher(reader);

            string[] searchFields = {"ProjectName", "Customer", "Country"};
            var queryParser = new MultiFieldQueryParser(LuceneVersion.LUCENE_48, searchFields, analyzer);
            queryParser.DefaultOperator = Operator.AND;
            var query = queryParser.Parse(queryString.ToLowerInvariant());

            int maxNumHits = 10;
            var topDocs = searcher.Search(query, maxNumHits);

            return topDocs.ScoreDocs.Select(hit => $"Score {hit.Score,5:0.000} DocId {hit.Doc}").ToList();
        }

        static void Main(string[] args)
        {
            Console.WriteLine("=================");

            string indexDir = CreateTestIndex();
            IList<string> hitsOne = Search(indexDir, "Germany");
            IList<string> hitsTwo = Search(indexDir, "Country:Germany");

            Console.WriteLine($"Search one yields {hitsOne.Count} hits.");
            Console.WriteLine($"Search two yields {hitsTwo.Count} hits.");

            Console.WriteLine("=================\n\n");
        }
    }
}

I found the mistake I made.我发现了我犯的错误。 Apparently, field names in Lucene are case-sensitive.显然,Lucene 中的字段名称是区分大小写的。 Hence, in my case the code queryString.ToLowerInvariant() turned the query string "Country:Germany" into "country:Germany" and, thus, nothing was found, because the lower-case field country does not exist.因此,在我的例子中,代码queryString.ToLowerInvariant()将查询字符串"Country:Germany"转换为"country:Germany" ,因此没有找到任何内容,因为小写字段country不存在。

Solution: Remove the call to ToLowerInvariant() .解决方案:删除对ToLowerInvariant()的调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM