当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch:为关键字的大小写不敏感搜索添加规范化器

诸修伟
2023-03-14

我有一个带有动态创建的“关键字”字段的大型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
}

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

共有3个答案

柳深
2023-03-14

这可以使用动态模板的概念。我们可以定义如下所示的动态映射,将名称为“my\u 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"
          }
        }
      }
    ]
  }
}
慕容晔
2023-03-14

目前,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

这意味着您要创建的资源已经存在,因此我们不能创建相同的资源,这里的资源意味着名为category\u video\u autocomplete\u 3的索引。

卫胜
2023-03-14

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

 类似资料:
  • 问题内容: 这是我的mysql表的架构,即时通讯使用mysql 5 需要敏感的UNIQUE KEY大小写, 它应该允许输入类似(’a’,0)&(’A’,0)的值 尝试将排序规则更改为latin_1和latin_generic_ci 问题答案: 最简单的是在DDL语句上添加, SQLFiddle演示

  • 我试图在elasticsearch中对术语聚合的桶进行排序,不区分大小写。以下是字段映射: 请注意,此处的此数据结构适用于PHP。 聚合如下所示: 这是可行的,但生成的桶是按字典顺序排列的。 我在这里找到了一些有趣的文档,它们解释了如何做到这一点,但这是在对点击进行排序的上下文中,而不是在聚合桶中。 我还是试过了。以下是我创建的分析器: 这里是更新的字段映射,使用分析器有一个名为“sort”的新子

  • 问题内容: 默认情况下,django的url解算器似乎执行区分大小写的搜索来解析url,并区分’/ Login’和’login’。我的网址格式如下。 谁能指导我,如何使Django URL不区分大小写? 问题答案: 只需放在每个字符串的开头,即: 告诉每个RE不区分大小写地匹配

  • 在执行MySQL 数据库给数据表改名时,发现报错,如下: 从提示中可以看出 blog_comment,表已经存在,可登录 MySQL 客户端查看数据表,并没有看到这张表。 提示中所说目标表并不存在。手动执行改名SQLRENAME TABLE blog_Comment TO blog_comment;,报同样错误:Table 'blog_comment' already exists。 从网上找一些

  • 问题内容: 我尝试在elasticsearch.yml文件中创建一个条目,以针对要点中提到的内容创建自定义分析器: https //gist.github.com/1403902 但我得到以下错误 我仍然不知道如何做到这一点。我已经在stackoverflow上搜索了相同的内容,并得到了类似的回复(如上述要点所述) 请给我一个例子,我可以测试。 问题答案: 由于配置文件在启动时是只读的,因此要使更

  • 问题内容: 我正在尝试考虑在PHP中实现不区分大小写的file_exists函数的最快方法。我最好的选择是枚举目录中的文件,并进行strtolower()与strtolower()的比较直到找到匹配项? 问题答案: 我使用注释中的源代码来创建此功能。返回完整路径文件(如果找到),否则返回FALSE。 在文件名中的目录名称上不区分大小写。