带有“&”的同义词过滤器不使用elasticsearch建议使用标准标记生成器

时间:2015-08-10 18:14:45

标签: elasticsearch tokenize autosuggest

我的目标是,如果我有"s & p indices"索引的内容,如果用户搜索s and ps & ps p,我也可以建议您这样做。然而,似乎有一些特殊的& amp;因为下面的同义词设置不起作用。我有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的同义词按预期工作。

我认为它可能与标准标记器如何标记和&有关,但我不知道如何解决这个问题。有没有办法让令牌器排除&分离和/或以不同方式对待它?

2 个答案:

答案 0 :(得分: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
      }
   ]

标准标记器吃掉&amp ;.让这一切在这里工作的最简单方法是改变你的分析仪使用空白分析器,它不会去除特殊字符或做很多工作,它的工作是分裂在空白区域。

我将您的映射修改为:

  "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
            }
         ]
      }
   ]
}

答案 1 :(得分:1)

另一种选择是在使用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",
                    ]
                }
            }
            ...