我创建了一个公司类型。在该公司类型的内部,我有一个名为" Summary"的字段。如何在此字段中添加多个索引分析器?
我简要介绍了如何使用Yakaz插件,但它似乎并不能用于NEST。
这背后的原因是,有时用户会在查询中搜索带有句点的公司名称,有时候他们不会包含句号。我想在有和没有标点符号的公司名称上使用ngrams进行部分匹配。我目前正在使用停用词过滤器来删除标点符号。
摘要字段的属性(让多个索引分析器抛出错误):
[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))
)
);
}
或者,如果有办法在单个分析仪中执行此操作,我可以接受建议。
编辑:
我的班级名称是&#34; ElasticSearchProject&#34;。我希望将它存储为名为&#34; Project&#34;的类型。我相信我对此的尝试是造成错误的原因。当我获得类型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"))
))))
答案 0 :(得分:5)
首先,要回答您的问题,您无法将多个分析器添加到单个字段中。但是,您可以使用multi field类型映射同一字段的多个版本,并为每个版本应用不同的分析器。查看此answer以了解如何使用NEST完成此操作。
关于使用和不使用标点符号进行搜索,如果您使用与索引和搜索分析器相同的分析器,那么它无关紧要,因为在索引期间应用于该字段的相同分析也将应用于用户查询。
示例:
Foo.Bar
将被编入索引为foobar
。
如果用户搜索Foo.Bar
或FooBar
,搜索分析器会将其转换为foobar
,并且会找到匹配项,因为该字段也被编入索引{{1} }。
我认为您的部分问题是您尝试使用foobar
作为搜索分析器,full_match
和partial_match_no_punctuation
作为索引分析器。尝试将它们合并为一个(删除标点符号,ngrams),并将其用于搜索和索引分析器。如果您发现仍需要多个分析仪,请查看我上面提到的多字段类型。
希望有所帮助。
编辑:根据您的更新,您的多字段映射的问题是您尝试为这两个字段分配相同的名称。此外,您正在命名字段&#34; project&#34;,这是您的类型的名称,可能您想要命名它&#34; summary&#34;代替。此外,您不希望将“我的ID”字段作为“摘要”多字段的一部分。试试这个:
partial_match
这将在您的映射中创建两个字段:
使用.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.no_puncuation
。