本文已收录至Github,推荐阅读 👉 Java随想录
微信公众号:Java随想录
Mapping 也称之为映射,定义了 ES 的索引结构、字段类型、分词器等属性,是索引必不可少的组成部分
ES 中的 Mapping 有点类似于关系型数据库中“表结构”的概念,在 MySQL 中,表结构里包含了字段名称,字段的类型还有索引信息等。在 Mapping 里也包含了一些属性,比如字段名称、类型、字段使用的分词器、是否评分、是否创建索引等属性。
//查看索引完整的mapping
GET /my_index/_mappings
//查看索引指定字段的mapping
GET /my_index/_mappings/field/field_name
例如,如果你有一个名为 “my_index” 的索引,并且你想查询字段 “my_field” 的 mapping,那么请求就像这样:
GET /my_index/_mapping/field/my_field
此请求会返回如下类型的输出:
{
"my_index" : {
"mappings" : {
"my_field" : {
"full_name" : "my_field",
"mapping" : {
"my_field" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
在这个响应中,你可以看到 “my_field” 是 “text” 类型,并且它也有一个子字段 “keyword”。
映射的数据类型也就是 ES 索引支持的数据类型,其概念和 MySQL 中的字段类型相似,但是具体的类型和 MySQL 中有所区别,最主要的区别就在于 ES 中支持可分词的数据类型,如:Text 类型,可分词类型是用以支持全文检索的,这也是 ES 生态最核心的功能。
env
的值可能为 “production”。JSON 没有日期数据类型,因此 Elasticsearch 中的日期可以是以下三种:
rank_feature
类似,但它能够处理包含多个特征的对象。当这些字段被查询时,Elasticsearch 会考虑它们的值来重新排序搜索结果。Elasticsearch的Dynamic Field Mapping是一种自动产生index mapping的机制。在通常情况下,当一个新文档被索引到Elasticsearch中,如果其中包含了未在mapping中定义的字段,Elasticsearch就会尝试根据这个新字段的数据类型自动生成相应的mapping。
自动映射关系如下:
field type | dynamic |
---|---|
true/false | boolean |
小数 | float |
数字 | long |
object | object |
数组 | 取决于数组中的第一个非空元素的类型 |
日期格式字符串 | date |
数字类型字符串 | float/long |
其他字符串 | text + keyword |
除了上述字段类型之外,其他类型都必须显式映射,也就是必须手工指定,因为其他类型ES无法自动识别。
这里有几点需要注意:
dynamic
设置为false
。总的来说,虽然动态字段映射可以在某些情况下提供便利,但它也可能导致未预见的问题。因此,更推荐在开始索引文档之前就定义好mapping。
在 Elasticsearch 中,显式映射(Explicit Field Mapping)是指为索引预定义的字段类型和行为。当你创建一个索引时,你可以定义每个字段的数据类型、分词器或者其他相关的配置。这就是显式映射。
以下是一些主要的显式映射类型:
通过显式映射,Elasticsearch 可以更准确地解析和索引数据,对查询性能优化起到关键作用。如果不提供显式映射,Elasticsearch 将会根据输入数据自动推断并生成隐式映射,但可能无法达到最理想的效果。
以下是一个示例,展示了怎么设置一个简单的显式映射:
PUT my_index
{
"mappings": {
"properties": {
"name": { "type": "text" },
"age": { "type": "integer" }
}
}
}
上述代码中,我们在 my_index
索引中定义了两个字段的映射,name
字段类型为 text
,age
字段类型为 integer
。
注意:在 Elasticsearch 7.0 之后,映射类型被废弃,所有的映射参数直接放在 “properties” 下。
在Elasticsearch中,映射参数是用于定义如何处理文档和其包含的字段的规则。
主要参数有下:
PUT my_index
{
"mappings": {
"enabled": false
}
}
"date": {
"type": "date",
"format": "yyyy-MM-dd"
}
当一个字段是要被全文检索时,比如 Email 内容、产品描述,这些字段应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引之前,字符串会被分析器分成一个个词项。text类型的字段不用于排序,很少用于聚合。
注意事项
Keyword 类型适用于不分词的字段,如姓名、Id、数字等。如果数字类型不用于范围查找,用 Keyword 的性能要高于数值类型。
当使用 Keyword 类型查询时,其字段值会被作为一个整体,并保留字段值的原始属性。
GET index/_search
{
"query": {
"match": {
"title.keyword": "测试文本值"
}
}
}
注意事项
ignore_above
参数代表其截断长度,默认 256,如果超出长度,字段值会被忽略,而不是截断,忽略指的是会忽略这个字段的索引,搜索不到,但数据还是存在的。之前讲过的映射类型或者映射参数,都是为确定的某个字段而声明的。
但是当我们不确定字段名字的时候该怎么设置mapping呢?映射模板就是用来解决这种场景的。
如果希望对符合某类要求的特定字段制定映射,就需要用到映射模板:Dynamic templates。映射模板有时也被称作:自动映射模板、动态模板等。
以下是一个示例:
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
},
{
"longs_as_integer": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
}
]
}
}
在上述例子中,我们定义了两个模板:strings_as_keyword
和 longs_as_integer
。当新字段被发现时,Elasticsearch 会检查这些模板以决定如何映射这个新字段。
strings_as_keyword
模板将所有新的字符串类型字段映射为 keyword
类型。longs_as_integer
模板将所有新的长整数(long)类型字段映射为 integer
类型。注意:这些只是示例,实际的映射应该取决于实际数据和查询需求。例如,如果你需要对字符串字段进行全文搜索,那么将其映射为 text
可能更合适。
match
:匹配字段名称。unmatch
:反匹配字段名称。match_mapping_type
:匹配字段类型,例如 string、long、double、boolean、date。match_pattern
:允许更复杂的名字模式,支持"starts_with"、“ends_with” 和 “contains”。path_match
:允许你用路径 (如 article.title) 来匹配字段。path_unmatch
:反匹配路径。mapping
:该字段被匹配时,应用的映射设置。PUT test_dynamic_template
{
"mappings": {
"dynamic_templates": [{
"integers": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
},
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "num_*",
"unmatch": "*_text",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
以上代码会产生以下效果: