Elasticsearch中<propertie>.keyword含义、字段差异及查询差异咨询
.keyword子字段 嘿,作为Elasticsearch新手,搞懂.keyword字段确实是入门的关键一步,我来给你拆解清楚所有疑问:
什么是.keyword属性?
在Elasticsearch中,字符串类型的字段默认会被映射成两个子字段:
- 一个是
text类型(比如你看到的locality),专门用于全文搜索 - 另一个就是
.keyword后缀的keyword类型字段(比如locality.keyword),用于精确匹配和聚合操作
你在Kibana的「Management」>「Index Pattern」里看到只有.keyword字段的aggregatable选项激活,是因为**text类型字段默认不支持聚合/排序**——它的设计目的是分词后做全文检索,而keyword类型会完整保留原始字符串,天生就适合分组统计、排序这类操作,所以Kibana会默认开启它的聚合权限。
locality 与 locality.keyword 的核心区别
直接对比两者的特性:
locality(text类型)- 会被分词器拆解:比如值是"Sant Climent",会被拆成
sant和climent两个独立词条 - 适用场景:全文搜索,比如想找到所有包含"sant"或者"climent"的文档
- 限制:默认无法用于聚合、排序
- 会被分词器拆解:比如值是"Sant Climent",会被拆成
locality.keyword(keyword类型)- 完全保留原始字符串:存储的就是完整的"Sant Climent",不会被分词
- 适用场景:精确匹配、聚合统计(比如统计每个地区的文档数量)、排序
- 优势:支持聚合操作,这就是你在Kibana里看到它的
aggregatable选项激活的原因
为什么两种match查询结果不同?
我们来拆解你提到的两个查询:
第一个查询:
{'match': {'locality': "Sant Climent"}}
这里用的是text类型的locality字段,Elasticsearch会先把查询字符串"Sant Climent"分词成sant和climent,然后返回所有包含这两个词条中任意一个的文档(默认是OR逻辑)。比如如果有文档的locality是"Sant Climent de Llobregat"或者"Climent Hill",都会被匹配到。第二个查询:
{'match': {'locality.keyword': "Sant Climent"}}
这里用的是keyword类型字段,查询字符串不会被分词,只会精确匹配值完全等于"Sant Climent"的文档。只有locality字段值就是"Sant Climent"的文档才会被返回,多一个字符、少一个字符或者大小写不同(除非你设置了忽略大小写的映射)都不会被匹配。
举个直观的例子:
假设你有三个文档:
- 文档1:
"locality": "Sant Climent" - 文档2:
"locality": "Sant Climent de Llobregat" - 文档3:
"locality": "Climent"
第一个查询会返回所有三个文档,第二个查询只会返回文档1。
快速总结使用场景
- 要做全文搜索,找包含关键词的文档 → 用
text字段(比如locality) - 要做精确匹配、统计分组、排序 → 用
keyword字段(比如locality.keyword)
内容的提问来源于stack exchange,提问作者RodriKing

