Mapping
Document 元数据字段
Field 数据类型
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
通用类型
- 二进制类型:以 Base64 字符串编码的二进制值。
- 布尔类型:true、false。
- 关键字类型:keyword,用于结构化内容,如ID、电子邮件地址、主机名、状态码、邮政编码或标签。 constant_keyword用于始终包含相同值的关键字字段。 wildcard用于非结构化的机器生成内容。wildcard(通配符)。
- 数字类型:long、double。
对象和关系类型
结构化数据类型
Multi Field 多重字段 当我们需要对一个字段进行多种不同方式的索引时,可以使用fields多重字段定义。如一个字符串字段即需要进行text分词索引,也需要进行keyword 关键字索引来支持排序、聚合;或需要用不同的分词器进行分词索引。
nested
array 扁平化与 nested 独立子文档
Lucene 中会将文档进行扁平化处理,需要手动指定nested构建层次关系
PUT /array2nested
{
"mappings": {
"properties": {
"array_field": {
"type": "object",
"properties": {
"field1": {"type": "keyword"},
"field2": {"type": "long"},
"field3": {"type": "date"}
}
},
"nested_field": {
"type": "nested",
"properties": {
"field1": {"type": "keyword"},
"field2": {"type": "long"},
"field3": {"type": "date"}
}
}
}
}
}
创建三个示例文档,其中每个文档的 array_field 和 nested_field 数据完全一样
POST /array2nested/_doc/1
{
"array_field": [
{"field1": "A", "field2": 10, "field3": "2025-09-20"},
{"field1": "B", "field2": 20, "field3": "2025-09-21"}
],
"nested_field": [
{"field1": "A", "field2": 10, "field3": "2025-09-20"},
{"field1": "B", "field2": 20, "field3": "2025-09-21"}
]
}
POST /array2nested/_doc/2
{
"array_field": [
{"field1": "A", "field2": 20, "field3": "2025-09-20"},
{"field1": "C", "field2": 30, "field3": "2025-09-22"}
],
"nested_field": [
{"field1": "A", "field2": 20, "field3": "2025-09-20"},
{"field1": "C", "field2": 30, "field3": "2025-09-22"}
]
}
POST /array2nested/_doc/3
{
"array_field": [
{"field1": "B", "field2": 20, "field3": "2025-09-21"},
{"field1": "C", "field2": 40, "field3": "2025-09-23"}
],
"nested_field": [
{"field1": "B", "field2": 20, "field3": "2025-09-21"},
{"field1": "C", "field2": 40, "field3": "2025-09-23"}
]
}
// Lucene 对数组扁平化处理:
// array_field.field1: ["B", "C"]
// array_field.field2: [20, 40]
// array_field.field3: ["2025-09-21", "2025-09-23"]
查询 field1 = A 且 field2 = 20,预期为查询结果为id=2的文档
// 查 object 数组
// _id=1、2 都命中
// 1 号文档里 A 和 20 并不在同一个对象,但被扁平化后混在一起了
GET array2nested/_search
{
"query": {
"bool": {
"must": [
{ "term": { "array_field.field1": "A" }},
{ "term": { "array_field.field2": 20 }}
]
}
}
}
// 查 nested 数组
// 只有 `_id=2` 命中 因为 nested 把每个对象当独立子文档,字段必须**同时出现在同一子文档**才算匹配。
GET array2nested/_search
{
"query": {
"nested": {
"path": "nested_field",
"query": {
"bool": {
"must": [
{ "term": { "nested_field.field1": "A" }},
{ "term": { "nested_field.field2": 20 }}
]
}
}
}
}
}
Mapping 参数
dynamic
https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dynamic
dynamic 用于控制包含非 mapping 定义字段的一个文档插入该索引时的行为。包含四种取值:
true:默认,新字段会被添加到映射中。runtime:新字段会作为运行时字段添加到映射中。这些字段不会被索引,会在查询时从_source中加载。false:新字段会被忽略。这些字段不会被索引,也无法搜索,但仍会出现在返回结果的_source字段中。这些字段不会被添加到映射中,新字段必须显式添加。strict:如果检测到新字段,会抛出异常并拒绝该文档。新字段必须显式添加到映射中。
coerce
https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/coerce
用于控制是否允许对文档中的字段值进行强制类型转换。**默认值为 true**,即默认允许强制类型转换。当文档中的字段值类型与映射中定义的类型不匹配时,如果启用了 coerce,Elasticsearch 会尝试自动将该值转换为映射中定义的类型。如果禁用 coerce,则必须确保文档中的字段值类型与映射中定义的类型完全一致,否则会导致文档索引失败。
如果映射中定义字段类型为 integer,但文档中传入的是字符串 "123",启用 coerce 后,Elasticsearch 会自动将其转换为整数 123。如果传入的是 "abc",则转换失败,仍然会抛出异常。
[!IMPORTANT]
coerce 为 true 时启用强制类型转换,会以数据转换后的值建立索引,而 _source 中依然原样存储,有可能会造成定义类型与实际类型的不一致。例如,索引中 age 被定义为 long 类型,但创建文档时 age 值为
"18",则底层会以18建立索引,但查询文档时返回的 _source 中依然会是"18",且有可能文档创建时 age 值为18,这样会造成该索引中不同文档 _source 中返回类型不一样,以及 索引中字段类型与 _source 中类型不一样,为客户端处理数据造成问题。