【问题标题】:How to properly handle multi words synonym expansion using elasticsearch?如何使用elasticsearch正确处理多词同义词扩展?
【发布时间】:2019-09-20 11:31:59
【问题描述】:

我有以下同义词扩展:

suco => suco, refresco, bebida de soja

我想要以这种方式标记搜索:

搜索“suco de laranja”将被标记为 ["suco", "laranja", "refresco", "bebida de soja"]。

但我将其标记为 ["suco"、"laranja"、"refresco"、"bebida"、"soja"]。

考虑到“de”这个词是一个停用词。我希望它在查询中被忽略,例如“bebida de laranja”变成[“bebida”,“laranja”]。但我不希望在同义词标记化中考虑它,因此“bebida de soja”仍然作为一个标记“bebida de soja”。

我的设置:

{
    "settings":{
        "analysis":{
            "filter":{
                "synonym_br":{
                    "type":"synonym",
                    "synonyms":[
                        "suco => suco, refresco, bebida de soja"
                    ]
                },
                "brazilian_stop":{
                    "type":"stop",
                    "stopwords":"_brazilian_"
                }
            },
            "analyzer":{
                "synonyms":{
                    "filter":[
                        "synonym_br",
                        "lowercase",
                        "brazilian_stop",
                        "asciifolding"
                    ],
                    "type":"custom",
                    "tokenizer":"standard"
                }
            }
        }
    }
}

【问题讨论】:

    标签: elasticsearch elastic-stack elasticsearch-5


    【解决方案1】:

    我建议您进行以下两项更改。第一个与您提出的问题直接相关,第二个是建议。

    1. 不要使用多个同义词的扩展,而是执行相反的操作,即所有同义词都指向一个单词同义词。所以,把"suco => suco, refresco, bebida de soja"改成"suco, refresco, bebida de soja => suco"

    2. 更改synonyms 分析器中过滤器的顺序。将lowercase 放在synonym_br 之前。这将确保大小写不会影响synonym_br 令牌过滤器。

    所以最终设置将是:

    {
      "settings": {
        "analysis": {
          "filter": {
            "synonym_br": {
              "type": "synonym",
              "synonyms": [
                "suco, refresco, bebida de soja => suco"
              ]
            },
            "brazilian_stop": {
              "type": "stop",
              "stopwords": "_brazilian_"
            }
          },
          "analyzer": {
            "synonyms": {
              "filter": [
                "lowercase",
                "synonym_br",
                "brazilian_stop",
                "asciifolding"
              ],
              "type": "custom",
              "tokenizer": "standard"
            }
          }
        }
      }
    }
    

    这是如何工作的?

    对于输入bebida de soja,过滤器按以下顺序应用:

    Input Filter        Result tokens
    ====================================
    lowercase           bebida, de, soja
    synonym_br          suco             <------- all the above tokens(including position) exactly matches a synonym
    brazilian_stop      suco
    asciifolding        suco
    

    让我们看看brazilian_stop 的实际应用。为此,我们需要一个与同义词不匹配但包含de 的输入。例如。 de soja:

    Input Filter        Result tokens
    =================================
    lowercase           de, soja
    synonym_br          de, soja  <------- none of the tokens (independently or combined(including position)) matches any synonym
    brazilian_stop      soja      <------- de is removed as it is a stopword
    asciifolding        soja
    

    【讨论】:

    • 非常感谢您的回答,谢谢。但情况是产品名称是“refresco”,但产品的通用名称是 suco。所以我想要的是,当人们搜索“suco”时,他们会得到包含“suco”这个词以及“refresco”的产品。如果我将扩展同义词更改为您推荐的收缩,则会产生相反的效果。人们会搜索“refresco”并获得“suco”产品,但搜索“suco”只会匹配“suco”产品。我说的对吗?
    • refrescosuco 在索引时都将被标记为 suco。因此,假设 doc 1 有一个字段 product(分析器:同义词),其值为 refresco。它将被标记并索引为 suco,文档 2 可以说将 suco 作为 product 值,将被索引为 suco。如果用户搜索refresco,则搜索查询在匹配product 字段时将默认对搜索字符串使用相同的分析器;即对于refresco,弹性将应用synonyms 分析器,这将产生令牌suco。所以实际上它会匹配具有suco 的文档。因此两者都将按预期匹配。
    • @EduardoJunior 以上说得通吗?你的问题解决了吗?如果需要,请随时获得更多说明。
    猜你喜欢
    • 1970-01-01
    • 2023-01-10
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多