【问题标题】:ElasticSearch: Adding a normalizer for case-insensitive search on keywordElasticSearch:为关键字不区分大小写的搜索添加规范器
【发布时间】:2017-11-02 00:22:19
【问题描述】:

我有一个大型 ES 索引,其中包含动态创建的“关键字”字段。我需要对这些启用不区分大小写的搜索。我知道分析器不适用于关键字字段,而规范器将用于它:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-normalizers.html

有没有办法将规范化器动态添加到字段/映射?我可以通过关闭索引、添加分析器并重新打开索引来将分析器添加到现有文本字段。在添加规范化器时,这似乎不适用于现有索引。除了创建另一个索引来重新索引所有数据之外,还有其他方法吗?

这是我的步骤: 使用小写规范器创建测试索引:

curl -XPUT localhost:9200/ganesh_index/ -d '
{
  "settings": {
    "analysis": {
      "normalizer": {
        "useLowercase": {
          "type": "custom",
          "filter": [ "lowercase" ]
        }
      }
    }
  },
  "mappings":{
     "ganesh_type":{
        "properties":{
           "title":{
              "normalizer":"useLowercase",
              "type":"keyword"
           }
        }
     }
  }
}'

现在,我可以根据需要插入和查询:

curl -X PUT localhost:9200/ganesh_index/ganesh_type/1 -d '{"title":"ThisFox.StatusCode1"}'
curl -X PUT localhost:9200/ganesh_index/ganesh_type/2 -d '{"title":"ThisFox.StatusCode2"}'

curl -X POST 'localhost:9200/ganesh_index/_search?pretty' -d '{"query": {"regexp":{"title": "this.*code1"}}}'
{
  "took" : 24,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "ganesh_index",
        "_type" : "ganesh_type",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "ThisFox.StatusCode1"
        }
      }
    ]
  }
}

但是,如果我的索引已经存在,像这样:

curl -X PUT localhost:9200/ganesh_index -d '
{
  "settings": {
    "index": {
      "number_of_shards": 2,
      "number_of_replicas": 2
    }
  }
}'

我插入了记录,以后无法添加规范器。

curl -XPUT localhost:9200/ganesh_index/?pretty -d '
> {
>   "settings": {
>     "analysis": {
>       "normalizer": {
>         "useLowercase": {
>           "type": "custom",
>           "filter": [ "lowercase" ]
>         }
>       }
>     }
>   },
>   "mappings":{
>      "ganesh_type":{
>         "properties":{
>            "title":{
>               "normalizer":"useLowercase",
>               "type":"keyword"
>            }
>         }
>      }
>   }
> }'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "index_already_exists_exception",
        "reason" : "index [ganesh_index/mg5TckzaR5KZDE-FphTeDg] already exists",
        "index_uuid" : "mg5TckzaR5KZDE-FphTeDg",
        "index" : "ganesh_index"
      }
    ],
    "type" : "index_already_exists_exception",
    "reason" : "index [ganesh_index/mg5TckzaR5KZDE-FphTeDg] already exists",
    "index_uuid" : "mg5TckzaR5KZDE-FphTeDg",
    "index" : "ganesh_index"
  },
  "status" : 400
}

有没有办法为现有索引添加规范器(在关键字字段上)?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    不,您必须重新索引它或创建一个新映射。

    【讨论】:

      【解决方案2】:

      目前,Elasticsearch 不支持此类活动。 即使你这样做了,它也会给我们一个信息。

       {
        "error": {
          "root_cause": [
            {
              "type": "resource_already_exists_exception",
              "reason": "index [category_video_autocomplete_3/FkxOwP_RQMW_L077hYLPJg] already exists",
              "index_uuid": "FkxOwP_RQMW_L077hYLPJg",
              "index": "category_video_autocomplete_3"
            }
          ],
          "type": "resource_already_exists_exception",
          "reason": "index [category_video_autocomplete_3/FkxOwP_RQMW_L077hYLPJg] already exists",
          "index_uuid": "FkxOwP_RQMW_L077hYLPJg",
          "index": "category_video_autocomplete_3"
        },
        "status": 400
      }
      

      消息看起来很复杂,但仔细观察会发现

      resource_already_exists_exception
      

      表示你要创建的资源已经存在,所以我们不能创建相同的资源,这里的资源表示index名为category_video_autocomplete_3。

      【讨论】:

        【解决方案3】:

        这可以使用Dynamic templates 的概念来实现。 我们可以定义一个像下面这样的动态映射,它将名为“my_normalizer”的规范化器应用于所有未来的字符串类型的关键字字段。 但是,我们需要在创建索引之前将动态设置定义为映射的一部分,这样您就可以使用动态模板来定义自定义映射,这些映射可以根据匹配条件应用于动态添加的字段:

        PUT my-index
        {
          "settings": {
            "index": {
              "analysis": {
                "normalizer": {
                  "my_normalizer": {
                    "type": "custom",
                    "char_filter": [],
                    "filter": [
                      "lowercase"
                    ]
                  }
                }
              }
            }
          },
          "mappings": {
            "dynamic_templates": [
              {
                "strings": {
                  "match_mapping_type": "string",
                  "mapping": {
                    "type": "keyword",
                    "ignore_above": 256,
                    "normalizer": "my_normalizer"
                  }
                }
              }
            ]
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-15
          • 2018-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-25
          相关资源
          最近更新 更多