我有一个已创建的公司类型。在该公司类型的内部,我有一个名为“摘要”的字段。如何在此字段中添加多个索引分析器?
我简要地研究了使用Yakaz插件,但似乎无法与NEST一起使用。
其背后的原因是,有时用户会在查询中搜索带有句点的公司名称,而其他时候则不包括句点。我想在公司名称上使用ngram进行部分匹配,带标点和不带标点。我目前正在使用停用词过滤器来删除标点符号。
摘要字段的属性(具有多个索引分析器将引发错误):
[ElasticProperty(IndexAnalyzer = "partial_match", IndexAnalyzer = "partial_match_no_punctuation", SearchAnalyzer = "full_match")] public string Summary { get; set; }
对应:
private static void CreateMapping(ElasticClient client) { var partialMatchNoPunctuation = new CustomAnalyzer { Filter = new List<string> { "standard", "lowercase", "asciifolding", "punctuation_filter", "name_ngrams" }, //Apply all filters before ngram Tokenizer = "standard" }; var partialMatch = new CustomAnalyzer { Filter = new List<string> { "standard", "lowercase", "asciifolding", "name_ngrams" }, //Apply all filters before ngram Tokenizer = "standard" }; var fullMatch = new CustomAnalyzer { Filter = new List<string> { "standard", "lowercase", "asciifolding" }, Tokenizer = "standard" }; client.CreateIndex(Settings.Default.IndexName, c => c .Analysis(descriptor => descriptor .TokenFilters(bases => bases .Add("name_ngrams", new NgramTokenFilter { MaxGram = 11, MinGram = 3 }) .Add("punctuation_filter", new StopTokenFilter { Stopwords = new List<string> {"."} }) ) .Analyzers(bases => bases .Add("partial_match", partialMatch) .Add("partial_match_no_punctuation", partialMatchNoPunctuation) .Add("full_match", fullMatch)) ) ); }
另外,如果有一种方法可以在单个分析仪中执行此操作,则可以提出建议。
编辑:
我的班级名称是“ ElasticSearchProject”。我希望将其存储为名为“ Project”的类型。我相信我的尝试是导致错误的原因。当我获得Project类型的映射时,它只应用了部分匹配分析器。
这是唯一仍应用于我的班级的ES属性:
[ElasticType(Name = "Project")]
多字段映射:
.AddMapping<ElasticSearchProject>(m => m .MapFromAttributes() .Properties(project=>project .MultiField(mf=>mf .Name("Project") .Fields(f=>f .Number(s=>s.Name(o=>o.Id).Index(NonStringIndexOption.no)) .String(s => s.Name(o => o.Summary).IndexAnalyzer("partial_match")) .String(s => s.Name(o => o.Summary).IndexAnalyzer("partial_match_no_punctuation")) ))))
首先,要回答您的问题,您不能将多个分析仪添加到一个字段中。但是,您可以使用多字段类型来映射同一字段的多个版本,并对每个版本应用不同的分析器。
关于带标点和不带标点的搜索,如果您使用与索引和搜索分析器相同的分析器,则没有关系,因为在索引编制过程中应用于字段的相同分析也将应用于用户查询。
例:
Foo.Bar将被索引为foobar。
Foo.Bar
foobar
如果用户搜索Foo.Bar或FooBar,则搜索分析器会将其转换为foobar,因为字段也被索引为,所以将找到匹配项foobar。
FooBar
我觉得你的问题的一部分是,你要使用full_match的搜索分析,并partial_match_no_punctuation和partial_match作为指数分析。尝试将它们调和为一个(删除标点符号,ngram),并将其用于搜索和索引分析器。如果发现仍然需要多个分析器,请查看我上面提到的多字段类型。
full_match
partial_match_no_punctuation
partial_match
希望能有所帮助。
编辑:根据您的更新,多字段映射的问题是您试图为两个字段分配相同的名称。此外,您正在命名字段“项目”,这是您的类型的名称,可能您想将其命名为“摘要”。另外,您也不想将“ Id”字段包含在“ Summary”多字段中。尝试以下方法:
.AddMapping<ElasticSearchProject>(m => m .MapFromAttributes() .Properties(project => project .MultiField(mf => mf .Name(o => o.Summary) .Fields(f => f .String(s => s.Name(o => o.Summary).Analyzer("partial_match")) .String(s => s.Name(o => o.Summary.Suffix("no_punctuation")).Analyzer("partial_match_no_punctuation")) )))));
这将在映射中创建两个字段:
summary与partial_match分析仪。
summary
summary.no_puncuation与partial_match_no_punctuation分析仪。
summary.no_puncuation