弹性搜索 按字段分组

use*_*240 2 elasticsearch elasticsearch-aggregation

我的索引中有以下数据。

{
"id":1,
"car_name" : "ABC-101"
},
{
"id":2,
"car_name" : "DEF-102"
},
{
"id":3,
"car_name" : "ABC-103"
}
Run Code Online (Sandbox Code Playgroud)

我的索引的映射是

{
  "car": {
    "mappings": {
      "_doc": {
        "properties": {
          "car_name": {
            "type": "text",
            "fielddata": true
          }
        }
      }
    }
  } 
}
Run Code Online (Sandbox Code Playgroud)

我运行以下查询

 localhost:9200/car/_doc/_search?pretty
Run Code Online (Sandbox Code Playgroud)

具有以下请求正文

{
"size" : 0,
"aggs" : {
    "genres" : {
        "terms" : { 
            "field" : "car_name"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

}

我得到以下回复

"buckets": [
    {
      "key": "ABC",
      "doc_count": 2
    },
    {
      "key": "DEF",
      "doc_count": 1
    },
    {
      "key": "101",
      "doc_count": 1
    },
    {
      "key": "102",
      "doc_count": 1
    },
    {
      "key": "103",
      "doc_count": 1
    }
]
Run Code Online (Sandbox Code Playgroud)

为什么不带实际的键ABC-101 和DEF-102 为什么ABC 和101 被视为分开的键。

Alw*_*nny 5

默认情况下,字符串字段analyzed位于 elasticasearch 中。这意味着 "ABC-101"被索引为 2 个术语"ABC""101"。您的查询也会被分析,并且无论它们之间有哪些特殊字符,它也会被转换为 2 个术语“ABC”和“101”。

这就是为什么他们是匹配的所有字符串的相隔-ABC,101,DEF,102等。

例如

  {
  "car": {
    "car_name": "string",
    "fields": {
      "raw": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }  
  }
Run Code Online (Sandbox Code Playgroud)

如果要完全按原样搜索此字段,则应将其重新索引为 "index":"not_analyzed"

你可以让它keyword在 car_name 字段上工作以完全匹配

{
  "size" : 0,
  "aggs" : {
      "genres" : {
          "terms" : { 
              "field" : "car_name.keyword"
          }
      }
  }
Run Code Online (Sandbox Code Playgroud)

  • 使用“keyword”类型是当前的最佳实践,“not_analyzed”“string”已成为过去。 (3认同)