0

我正在将 Lucene.Net v3.0.3 与 C# 一起使用,并且在从 ConstantScoreQuery 中检索所有术语时遇到问题。方法 ExtractTerms 似乎是未编码的。

目标是获取与通配符搜索匹配的所有术语(使用 QueryParser) 我尝试使用 WildcardTermEnum 类,但使用 erf* && poli* 之类的组合通配符搜索失败

我该如何解决这个问题?

谢谢你。

4

1 回答 1

0

您的 WildcardQuery 被重写为BooleanQueryof ConstantScoreQueries,它实际上不是一个,Query而是一个过滤器。这就是为什么 ExtractTerms 不会为您提供任何东西的原因。

这是一种方法,虽然我同意这并不理想,但它是我能迅速提出的最好方法。这仅适用于前缀查询,如果您希望它与任何查询一起使用,则必须添加更多逻辑MultiTermQueries类型,则必须添加更多逻辑。

您必须在查询被重写之前执行此操作,否则它将不起作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Search.Spans;
using Lucene.Net.Analysis;
using Lucene.Net.Store;
using System.IO;
using Lucene.Net.QueryParsers;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            RAMDirectory dir = new RAMDirectory();
            IndexWriter iw = new IndexWriter(dir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED);

            Document d = new Document();
            Field f = new Field("text", "This is some erfand erftyas poliot polioasd poliasdas data to test the wild card term enums. Lets see how it works out.", Field.Store.YES, Field.Index.ANALYZED);
            d.Add(f);

            iw.AddDocument(d);

            iw.Commit();
            IndexReader reader = iw.GetReader();
            QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "text", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));            
            // parser.MultiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE;

            Query q= parser.Parse("(poli* && erf*) && test* && (asd* || res*) && aterm");
            Query q2 = parser.Parse("poli*");

            //var rq = q.Rewrite(reader);
            //ISet<Term> terms = new HashSet<Term>();
            //rq.ExtractTerms(terms);

            List<PrefixQuery> prefixQueries = null;
            if (q is PrefixQuery)
            {
                prefixQueries = new List<PrefixQuery>();
                prefixQueries.Add(q as PrefixQuery);
            }
            else if(q is BooleanQuery)
            {
                prefixQueries = ExtractQueries(q as BooleanQuery);
            }

            foreach (var pq in prefixQueries)
            {
                WildcardTermEnum termEnum = new WildcardTermEnum(reader, new Term(pq.Prefix.Field, pq.Prefix.Text + "*"));

                if (termEnum.Term != null)
                    Console.WriteLine(termEnum.Term.Text);
                while (termEnum.Next())
                {
                    Console.WriteLine(termEnum.Term.Text);
                }
            }

            Console.ReadLine();
        }

        private static List<PrefixQuery>  ExtractQueries (BooleanQuery query)
        {
            List<PrefixQuery> queries = new List<PrefixQuery>();
            foreach (var q in query)
            {
                if (q.Query is BooleanQuery)
                {
                    queries.AddRange(ExtractQueries(q.Query as BooleanQuery));
                }
                else
                {
                    if (q.Query is PrefixQuery)
                    {
                        queries.Add(q.Query as PrefixQuery);
                    }
                }
            }
            return queries;
        }
    }
}
于 2013-04-04T18:04:05.807 回答