这里的ES新手,正在寻求帮助以了解问题所在。
让我们考虑一下这个索引映射,在这里我为摩托车模型定义了一些同步词:
{
"settings": {
"analysis": {
"char_filter": {
"replace": {
"type": "mapping",
"mappings": [
"&=> and "
]
}
},
"filter": {
"word_delimiter": {
"type": "word_delimiter",
"split_on_numerics": "false",
"split_on_case_change": "true",
"generate_word_parts": "true",
"generate_number_parts": "true",
"catenate_all": "true",
"preserve_original": "true",
"catenate_numbers": "true"
},
"custom_synonym": {
"type": "synonym",
"lenient": "true",
"synonyms": [
"r 1200 r , r1200 r, r 1200r, r1200r",
"r 1150 r, r1150 r, r 1150r, r 1150 r, r1150r"
]
}
},
"analyzer": {
"default": {
"type": "custom",
"char_filter": [
"html_strip",
"replace"
],
"tokenizer": "whitespace",
"filter": [
"custom_synonym",
"lowercase",
"word_delimiter"
]
}
}
}
},
"mappings": {
"product": {
"properties": {
"pname": {
"type": "text",
"analyzer": "default"
}
}
}
}
}
如果我将两个文档放入索引:
PUT test_index/product/1
{
"pname" : "MOTORBIKE BMW R 1150 R"
}
PUT test_index/product/2
{
"pname" : "MOTORBIKE BMW R 1200 R"
}
然后执行匹配查询,如:
GET test_index/_search
{
"query": {
"match" : {
"pname" : "MOTORBIKE R1200R"
}
}
}
我的两个匹配都得分相同:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "test_index",
"_type" : "product",
"_id" : "2",
"_score" : 0.2876821,
"_source" : {
"pname" : "MOTORBIKE BMW R 1200 R"
}
},
{
"_index" : "test_index",
"_type" : "product",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"pname" : "MOTORBIKE BMW R 1150 R"
}
}
]
}
}
我希望在“ MOTORBIKE BMW R 1200 R”文档中获得更高的分数,因为我为“ r1200r”术语定义了一个同义词:( r 1200 r,r1200 r,r 1200r,r1200r)。>
有任何线索吗?
答案 0 :(得分:0)
我终于有时间对您的示例进行一些测试。我尝试尽可能多地解释,让我指出为使其起作用而进行了两项更改:
1)在您的设置中,将分析仪更改为:
"analyzer": {
"default": {
"type": "custom",
"char_filter": [
"html_strip",
"replace"
],
"tokenizer": "whitespace",
"filter": [
"lowercase",
"word_delimiter",
"custom_synonym"
]
}
}
查看过滤器部分。如我所说,顺序很重要。您要先小写,然后标记(在应用同义词之前)。这可能是导致令牌混乱的原因。实际上,同义词也被标记化。如果您使用此分析器分析同义词(例如“ r 1200 r”),则输出将非常庞大。我尝试举一个例子,在此我描述标记及其在索引中的位置:[token](position):
索引“ r 1200 r”将索引以下“树”:
这是因为,因为您定义同义词的方式意味着,elasticsearch会扩展并会索引您定义的所有可能的组合。您还可以看到,实际搜索'r'会产生结果,因为r只是一个标记-即使在索引r1200r时也是如此。
2)现在,我认为这不是您想要的,所以我将同义词定义更改为收缩样式表示法:
"custom_synonym": {
"type": "synonym",
"lenient": "true",
"synonyms": [
"r 1200 r , r1200 r, r 1200r => r1200r",
"r 1150 r, r1150 r, r 1150r, r 1150 r => r1150r"
]
}
基本上可以转换标记[r] [1200] [r]等,并且仅在箭头右边标明该术语:r1200r。请阅读以下文章以获取更多信息-整个过程相当复杂,需要对所需的预期行为进行很多思考:https://www.elastic.co/guide/en/elasticsearch/guide/master/synonyms-expand-or-contract.html
但是,使用此定义,仅搜索'r'将不再产生任何结果。并且,搜索“ MOTORBIKE R1200R”应始终返回ID为2的文档在最上面。而且无论是“ motorrike r 1200r”还是任何变体,得分都应保持不变。
但是请注意,使用此解决方案时,仅搜索1200或1150不会返回任何匹配项,因为当由同义词过滤器处理时1200永远不是索引项。 (当然,如果您仅索引“ bla bla 1200”,则例外,因为同义词将与此不匹配。
同义词,尤其是多词同义词很难处理。我知道我对链接文档有点讨厌,但是值得阅读整章的内容。 https://www.elastic.co/guide/en/elasticsearch/guide/master/synonyms.html
的子章节不过,如果您对我的回答有特定疑问,请随时发表评论。如果有时间,我将尝试更新并澄清我的答案。