我们可以在弹性搜索中将char_filter应用于自定义令牌生成器吗?

时间:2019-03-06 12:48:01

标签: elasticsearch

我已经在Elasticsearch中设置了一个自定义分析器,该分析器使用edge-ngram标记器,并且我正在尝试使用过滤器和char_filters来改善搜索体验。

我已经指出了出色的工具elyser,它使您能够测试自定义分析器对特定术语的影响,但是当我将自定义分析器与char_filter(特别是html_strip)结合使用时,这会引发错误。

我从elyser得到的错误是:

  

illegal_argument_exception”,“原因”:“自定义规范化器可能不使用   字符过滤器[html_strip]'

我想知道这是合法的错误消息,还是代表工具中的错误。

我已经参考了主要文档,甚至他们的custom analyser示例在elyser中也会引发错误:

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type":      "custom", 
          "tokenizer": "standard",
          "char_filter": [
            "html_strip"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  }
}

elyser中的命令:

elyzer --es "http://localhost:9200" --index my_index --analyzer my_custom_analyzer "Trinity Chapel <h1>[in fact King's Chapel]</h1>"

如果事实证明elyser有故障,谁能指出我另一种检查自定义分析器产生的令牌的方法,以便我可以测试每个过滤器的影响?

我的自定义分析器看起来有点像我向厨房扔了水槽,我想要一种测试和重构的方法:

PUT /objects
{
  "settings" : {
    "index" : {
      "number_of_shards" : "5",
      "analysis" : {
        "analyzer" : {
          "search_autocomplete": {
            "type": "custom",
            "tokenizer": "standard",
            "char_filter" : [
              "html_strip"
            ],
            "filter": [
              "standard",
              "apostrophe",
              "lowercase",
              "asciifolding",
              "english_stop",
              "english_stemmer"
          ] 
          },
          "autocomplete": {
            "type": "custom",
            "tokenizer": "autocomplete",
            "filter": [
                "standard",
                "lowercase",
                "asciifolding",
                "english_stop",
                "english_stemmer"
            ]
          },
          "title_html_strip" : {
            "filter" : [
              "standard",
              "lowercase"
            ],
            "char_filter" : [
              "html_strip"
            ],
            "type" : "custom",
            "tokenizer" : "standard"
          }
        },
        "tokenizer": {
          "autocomplete": {
            "type": "edge_ngram",
            "min_gram": 3,
            "max_gram": 20,
            "token_chars": [
              "letter",
              "digit"
            ]
          }
        },
        "filter": {
          "english_stop": {
            "type": "stop",
            "stopwords": "_english_"
          },
          "english_stemmer": {
            "type": "stemmer",
            "name": "english"
          }
        }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:1)

此错误在elyzer中。为了在分析过程的每个步骤中显示令牌的状态,elyzer对每个阶段执行一个分析查询:first char filters,然后是tokenizer,最后是token filters

问题是,在ES方面,自从他们引入normalizers(以非向后兼容的方式)以来,分析过程已经改变。 They assume如果请求中没有规范化器,分析器和令牌化器,但令牌过滤器或char_filter,则分析请求的行为应类似于规范化器。

在您的情况下,elyzer首先会请求html_strip字符过滤器,而ES会认为这与规范化有关,因此the error you're getting因为html_strip不是有效的{{ 1}}用于规范化器。

由于我非常了解Elyzer的开发人员(Doug Turnbull),所以我已经filed a bug。我们将看到发生的事情。

答案 1 :(得分:1)

检查自定义分析器生成的令牌的另一种方法:

官方文档中包含有关使用_analyse method的部分,并附带了explain:true标志,向我提供了详细信息,以审查我的自定义分析器。

以下内容在每个过滤器阶段输出令牌

pip install my_package --upgrade