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
的条款的最佳方法,但这是一个良好的开端