You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

开启fielddata后Elasticsearch获取字段唯一值异常求助

解决Elasticsearch聚合text字段时被拆分的问题

你的问题根源在于vip_nametext类型字段,这类字段默认会被分词器(比如标准分词器)拆分内容——像你的域名ppcbcl00021.domain.com会被拆成ppcbcl00021domain.com两个独立的词,所以即使开启了fielddata,聚合的也是分词后的碎片,而非完整的原始值。

正确的解决方法(优先推荐第一种)

1. 使用字段的keyword子字段聚合

很多时候创建text字段时,Elasticsearch会自动生成一个同名的keyword子字段(专门用于精确匹配、聚合和排序)。你可以直接聚合这个子字段:

curl -XGET http://172.31.38.157:9200/cb_inventory/_search?pretty=true -d '{
  "size":0,
  "aggs":{
    "vips":{
      "terms":{
        "field":"vip_name.keyword",
        "size":1000
      }
    }
  }
}'

这样就能得到完整的ppcbcl00021.domain.com作为唯一聚合值了。

2. 手动添加keyword子字段(如果没有自动生成)

如果你的mapping里没有vip_name.keyword,可以先更新mapping添加这个子字段:

curl -XPUT http://172.31.38.157:9200/cb_inventory/_mapping -d '{
  "properties":{
    "vip_name":{
      "type":"text",
      "fields":{
        "keyword":{
          "type":"keyword",
          "ignore_above":256
        }
      }
    }
  }
}'

注意:更新mapping后,旧数据不会自动生成keyword子字段的值,你需要重新索引现有数据(比如用Elasticsearch的_reindex API),之后再用vip_name.keyword执行聚合查询。

3. 将字段改为keyword类型(不推荐,除非不需要全文搜索)

如果这个字段不需要做全文搜索,你可以把它改成keyword类型,但这需要重建整个索引(因为Elasticsearch不允许直接修改已有字段的类型):

  • 先创建一个新索引,把vip_name设为keyword类型
  • _reindex API把旧索引的数据迁移到新索引
  • 之后用新索引执行聚合查询

为什么不推荐开启fielddata?

开启fielddata虽然能让text字段支持聚合,但它是把分词后的词加载到内存中,不仅会占用大量内存,而且本质上还是聚合分词后的碎片,解决不了你需要完整值的需求。而keyword字段是存储原始的完整值,磁盘存储更高效,也能直接满足精确聚合的需求。

内容的提问来源于stack exchange,提问作者user2405589

火山引擎 最新活动