C# Lucene.Net NGramAnalyzer使用引用的Ngram生成查询,例如[titleNGram:“他的ist存储”而不是[titleNGram:他的ist存储]
跟随 我创建了这个自定义分析器C# Lucene.Net NGramAnalyzer使用引用的Ngram生成查询,例如[titleNGram:“他的ist存储”而不是[titleNGram:他的ist存储],c#,lucene.net,C#,Lucene.net,跟随 我创建了这个自定义分析器 public class NGramAnalyzer : Analyzer { private readonly Version _version; private readonly int _minGram; private readonly int _maxGram; public NGramAnalyzer(Version version, int minGram = 2, int maxGram = 8) {
public class NGramAnalyzer : Analyzer
{
private readonly Version _version;
private readonly int _minGram;
private readonly int _maxGram;
public NGramAnalyzer(Version version, int minGram = 2, int maxGram = 8)
{
_version = version;
_minGram = minGram;
_maxGram = maxGram;
}
public override TokenStream TokenStream(string fieldName, TextReader reader)
{
// Splits words at punctuation characters, removing punctuation.
// Splits words at hyphens, unless there's a number in the token...
// Recognizes email addresses and internet hostnames as one token.
var tokenizer = new StandardTokenizer(_version, reader);
TokenStream filter = new StandardFilter(tokenizer);
// Normalizes token text to lower case.
filter = new LowerCaseFilter(filter);
// Removes stop words from a token stream.
filter = new StopFilter(true, filter, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
return new NGramTokenFilter(filter, _minGram, _maxGram);
}
}
我遇到的问题是,它以
[ titleNGram:"his ist sto tor ory" ] instead of [ titleNGram:his ist sto tor ory]
为了[历史]。注意第一页的引号
我如何使它不引用查询
我在这里发现了Java Lucene的类似讨论
有没有一种方法可以解决这个问题而不会导致解决方案
我使用的是PerfielDanalyzerRapper,似乎使用该解决方案并不干净
感谢任何帮助我想在我自己的自动完成实现中使用一个
NGramAnalyzer
,这是我唯一能找到的制作我想要的东西的尝试,所以这就是我开始的地方
我遇到了与您描述的相同的问题,并且提出了一个相当干净的解决方法
原因似乎在QueryParser.cs:494的Query GetFieldQuery(String-field,String-queryText)
中。这最终被称为QueryParser.Parse
的一部分。如果要向查询添加多个标记(“his”、“ist”等多个标记),并且名为SevertOkenSatSamePosition
的布尔值为false,则GetFieldQuery
构造短语查询(在第677行),并在返回之前向其添加所有标记(第705行)
我们想要的是将所有标记添加到一个布尔查询中,并使用出现。SHOULD
。我试图将QueryParser
子类化,并覆盖GetFieldQuery
,因为它标记为virtual
。然而,我需要复制其余的功能,并发现有相当多的private
变量引用。相反,在运行搜索之前,我找到了如何从解析的查询中提取标记并将其插入布尔查询中的方法:
var query = new BooleanQuery();
foreach( var word in terms ) {
var parsed = parser.Parse( word );
var extractedTerms = new HashSet<Term>();
parsed.ExtractTerms( extractedTerms );
foreach( var term in extractedTerms ) {
query.Add( new TermQuery( term ), Occur.SHOULD );
}
}
var resultDocs = searcher.Search( query, maxResults ).ScoreDocs;
var query=new BooleanQuery();
foreach(术语中的var单词){
var parsed=parser.Parse(word);
var extractedTerms=new HashSet();
已解析的.ExtractTerms(extractedTerms);
foreach(提取项中的var项){
query.Add(新术语query(term),occure.SHOULD);
}
}
var resultDocs=searcher.Search(查询,maxResults).ScoreDocs;
这似乎奏效了。我仍在努力确定minGram
和maxGram
的最佳值,以及处理长度小于minGram
的条款的最佳方法,但这是一个良好的开端