我正在将 Lucene.Net v3.0.3 与 C# 一起使用,并且在从 ConstantScoreQuery 中检索所有术语时遇到问题。方法 ExtractTerms 似乎是未编码的。
目标是获取与通配符搜索匹配的所有术语(使用 QueryParser) 我尝试使用 WildcardTermEnum 类,但使用 erf* && poli* 之类的组合通配符搜索失败
我该如何解决这个问题?
谢谢你。
我正在将 Lucene.Net v3.0.3 与 C# 一起使用,并且在从 ConstantScoreQuery 中检索所有术语时遇到问题。方法 ExtractTerms 似乎是未编码的。
目标是获取与通配符搜索匹配的所有术语(使用 QueryParser) 我尝试使用 WildcardTermEnum 类,但使用 erf* && poli* 之类的组合通配符搜索失败
我该如何解决这个问题?
谢谢你。
您的 WildcardQuery 被重写为BooleanQuery
of 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;
}
}
}