【问题标题】:Synonym filter with "&" not working in elasticsearch suggest with standard tokenizer带有“&”的同义词过滤器在弹性搜索中不起作用建议使用标准标记器
【发布时间】:2015-08-10 18:14:44
【问题描述】:

我的目标是,如果我有类似"s & p indices" 的索引,那么如果用户搜索s and ps & ps p,我也可以提出这个建议。但是,& 似乎有些特殊之处,因为下面的同义词设置不适用于它。我的suggest index 有以下映射。

{
  "settings": {
    "analysis": {
      "analyzer": {
        "suggest_analyzer": {
          "type":      "custom",
          "tokenizer": "standard",
          "filter":    [ "lowercase", "my_synonym_filter" ]
        }
      },
      "filter": {
        "my_synonym_filter": {
          "type": "synonym", 
          "synonyms": [ "&, and", "foo, bar" ]
        }
      }
    }
  }
}

我的type 有以下映射

{
  "properties" : {
    "name" : { "type" : "string" },
    "name_suggest" : {
      "type" : "completion",
      "index_analyzer" :  "suggest_analyzer",
      "search_analyzer" : "suggest_analyzer"
    }
  } 
}

如果我索引以下对象:

{
  "name" : "s & p indices",
  "name_suggest" : { 
    "input" : [ "s & p indices"] 
  }
}

搜索s and 不会返回索引建议。但是,foo 和 bar 的同义词按预期工作。

我认为这可能与标准标记器在 & 上的标记方式有关,但我不知道如何解决这个问题。有没有办法让分词器排除 & 的拆分和/或区别对待?

【问题讨论】:

  • 当你索引s & p文档时你索引什么?
  • @IanGabes 我将要索引的对象添加到 OP。为了这个问题,很简单

标签: elasticsearch tokenize autosuggest


【解决方案1】:

您当前的问题显然在于为suggest_analyzer 选择标记器。标准标记器不会为& 生成标记,因此传递给过滤器的标记流看不到& 标记,因此他们无法替换它。您可以使用_analyze endpoint

查看其工作原理

在这种情况下,标准标记器生成的标记对于文本 s & p 如下所示

"tokens": [
      {
         "token": "s",
         "start_offset": 5,
         "end_offset": 6,
         "type": "<ALPHANUM>",
         "position": 1
      },
      {
         "token": "p",
         "start_offset": 9,
         "end_offset": 10,
         "type": "<ALPHANUM>",
         "position": 2
      }
   ]

标准分词器吃掉 &。在这里让一切正常工作的最简单方法是将分析器更改为使用空白分析器,它不会去除特殊字符或根本不会做很多工作,它的工作是在空白处分割。

我将您的映射修改为:

  "settings": {
    "analysis": {
      "analyzer": {
        "suggest_analyzer": {
          "type":      "custom",
          "tokenizer": "whitespace",
          "filter":    [ "lowercase", "my_synonym_filter" ]
        }
      },
      "filter": {
        "my_synonym_filter": {
          "type": "synonym", 
          "synonyms": [
              "&, and",
              "foo, bar" ]
        }
      }
    }
  }

你会得到这样的结果:

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "name_suggest": [
      {
         "text": "s and",
         "offset": 0,
         "length": 5,
         "options": [
            {
               "text": "s & p",
               "score": 1
            }
         ]
      }
   ]
}

【讨论】:

    【解决方案2】:

    另一种选择是在使用 char 过滤器之前替换 & 符号。像这样:

                ...
                "char_filter" : {
                    "replace_ampersands" : {
                        "type" : "mapping",
                        "mappings" : ["&=>and"]
                    }
                },
                "analyzer": {
                    "autocomplete": {
                        "type": "custom",
                        "tokenizer": "standard",
                        "char_filter" : ["replace_ampersands"],
                        "filter": [
                            "lowercase",
                            "addy_synonym_filter",
                            "autocomplete_filter",
                        ]
                    }
                }
                ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 2020-07-25
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多