映射是用于定义 ES 对索引中字段的存储类型、分词方式和是否存储等信息,就像数据库中的 Schema ,描述了文档可能具有的字段或属性、每个字段的数据类型。
只不过关系型数据库建表时必须指定字段类型,而 ES 对于字段类型可以不指定然后动态对字段类型猜测,也可以在创建索引时具体指定字段的类型。
对字段类型根据数据格式自动识别的映射称之为动态映射(Dynamic Mapping),我们创建索引时具体定义字段类型的映射称之为静态映射或显示映射(Explicit Mapping)。
在讲解动态映射和静态映射的使用前,我们先来了解下 ES 中的数据有哪些字段类型?之后我们再讲解为什么我们创建索引时需要建立静态映射而不使用动态映射。
Text 用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是被分词的,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。
分析过程允许 Elasticsearch 搜索单个单词中每个完整的文本字段。文本字段不用于排序,很少用于聚合。
Keyword 用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。Keyword 字段只能按其确切值进行搜索。
通过对字段类型的了解我们知道有些字段需要明确定义的,例如某个字段是 Text 类型还是 Keyword 类型差别是很大的,时间字段也许我们需要指定它的时间格式,还有一些字段我们需要指定特定的分词器等等。
如果采用动态映射是不能精确做到这些的,自动识别常常会与我们期望的有些差异。
所以创建索引的时候一个完整的格式应该是指定分片和副本数以及 Mapping 的定义,如下:
{
"my_index": {
"mappings": {
"order": {
"properties": {
"actionTime": {
"type": "long"
},
"cardID": {
"type": "keyword"
},
"cardNo": {
"type": "keyword"
},
"cardTypeID": {
"type": "keyword"
},
"channelKey": {
"type": "keyword"
},
"channelOrderKey": {
"type": "keyword"
},
"checkoutType": {
"type": "keyword"
},
"cityID": {
"type": "keyword"
},
"cityName": {
"type": "keyword"
},
"clientType": {
"type": "keyword"
},
"createTime": {
"type": "long"
},
"dueTotalAmount": {
"type": "double"
},
"groupID": {
"type": "keyword"
},
"groupName": {
"type": "keyword"
},
"isAlreadyPaid": {
"type": "keyword"
},
"latitude": {
"type": "keyword"
},
"longitude": {
"type": "keyword"
},
"msgID": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"operator": {
"type": "keyword"
},
"orderID": {
"type": "keyword"
},
"orderKey": {
"type": "keyword"
},
"orderRemark": {
"type": "keyword"
},
"orderState": {
"type": "keyword"
},
"orderStatus": {
"type": "keyword"
},
"orderSubType": {
"type": "keyword"
},
"orderTime": {
"type": "long"
},
"orderTotal": {
"type": "double"
},
"orderType": {
"type": "keyword"
},
"originTotalAmount": {
"type": "double"
},
"paidTotalAmount": {
"type": "double"
},
"payTransNo": {
"type": "keyword"
},
"promotionAmount": {
"type": "double"
},
"refundTotalAmount": {
"type": "double"
},
"shopID": {
"type": "keyword"
},
"shopName": {
"type": "keyword"
},
"shopOrderKey": {
"type": "keyword"
},
"shopRealAmount": {
"type": "double"
},
"stdChannelKey": {
"type": "keyword"
},
"thirdPartyAccount": {
"type": "keyword"
},
"thirdPartyAmount": {
"type": "double"
},
"thirdPartyChannel": {
"type": "keyword"
},
"thirdPartyCode": {
"type": "keyword"
},
"thirdPartyRemark": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"thirdPartyTransNo": {
"type": "keyword"
},
"thirdPartyType": {
"type": "keyword"
},
"userID": {
"type": "keyword"
},
"userMobile": {
"type": "keyword"
},
"userName": {
"type": "keyword"
}
}
}
}
}
}
PUT my_index
{
"settings" : {
"number_of_shards" : 5,
"number_of_replicas" : 1
}
"mappings": {
"_doc": {
"properties": {
"title": { "type": "text" },
"name": { "type": "text" },
"age": { "type": "integer" },
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
}
}
}