编程随笔-ElasticSearch知识导图(3):映射

发布时间:2020-03-31 00:22:45 作者:简单是美美
来源:网络 阅读:951

1. 啥是映射

  ES中的映射(Mapping)实质上就是对文档对象结构的定义,也即对文档中各元素的描述。在ES中定义映射,就如同定义XML文档的XML Schema。
  ES中的映射定义了文档模式(就如同在关系数据库中定义了关系模式),文档模式确定了存在ES中的文档的格式,结构和字段的数据类型。通过查看某个索引的映射可以了解文档的结构,以便使用查询语言(Query DSL)构建更符合我们要求的查询命令。

2. 从一个示例开始

  让我们首先看一下如下关于银行账号的文档示例:

{
    "account_number": 1,
    "balance": 39225,
    "firstname": "Amber",
    "lastname": "Duke",
    "age": 32,
    "gender": "M",
    "address": "880 Holmes Lane",
    "employer": "Pyrami",
    "email": "amberduke@pyrami.com",
    "city": "Brogan",
    "state": "IL"
}

  ES对该文档的自动生成的映射是下面这个样子的:

{
    "bank": {
        "mappings": {
            "account": {
                "properties": {
                    "account_number": {
                        "type": "long"
                    },
                    "address": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "age": {
                        "type": "long"
                    },
                    "balance": {
                        "type": "long"
                    },
                    "city": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "email": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "employer": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "firstname": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "gender": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "lastname": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "state": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    }
                }
            }
        }
    }
}

  由这个自动生成的映射可以看到:ES自动将account_number、balance、age这些属性映射为long类型,其它的属性都映射为text类型。text类型的属性常用于全文搜索,但是并不进入内存中索引,因此text类型并不可用于聚合和排序(系统会报错:"Fielddata is disabled on text fields by default. Set fielddata=true on [address] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.")。
  ES允许为一个对象属性定义多个域(fields),每个域是该属性的一个facet(我思考很久,还是觉得这个词最合适),如“address”属性类型为text,为它定义 一个域为keyword,该域的类型为“keyword”,不会被分析器(analyzer)分析,可用于排序、聚合和精确查找(请注意ignore_above这个属性,限制了用于keyword的有效字符数目)。
  在DSL查询语言中查询时,使用“address”时,经分析器分析后,"880 Holmes Lane"可能被分解为“880”,“Holmes”,“Lane”进入全文搜索。看看下面的两个查询命令:

curl -iXGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json'  -d'
{"query":
    {"match":
       {"address.keyword":"880 Holmes Lane"}
    }
}'

  查询出来只有一个结果,精确匹配“880 Holmes Lane”。

curl -iXGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json'  -d'
{"query":
    {"match":
       {"address":"880 Holmes Lane"}
    }
}'

  查询出来多个结果,查询条件“880 Holmes Lane”被分析器分析后检索,"591 Nolans Lane"也被检索出来(其中包含了一个分析器分解后的Lane)。
  以一张图总结相关的知识点:
编程随笔-ElasticSearch知识导图(3):映射

3. 域的数据类型

  ES中域的主要数据类型如下表所示,还可由一些插件扩展数据类型(这里不赘述了):

数据类型 分类
text , keyword 字符串
long , integer , short , byte , double , float , half_float , scaled_float 数字
date 日期
boolean 布尔
binary 二进制
integer_range , float_range , long_range , double_range , date_range 区间类型
Array, object, nested 复杂数据类型
geo_point, geo_shape 地理数据类型
binary 二进制
ip, completion,token_count,percolator,join, alias 特殊数据类型

3.1. 核心数据类型

  核心数据类型与我们常使用的强类型语言中的数据类型类似,可分为以下几类:

参数 描述
analyzer 定义对文本数据的分析器
normalizer 对文本数据规范化
boost 用于提升字段搜索的权重
coerce 当为false时,强制输入值必须符合映射的域数据类型
copy_to 将当前域的值复制到另一个域中
doc_values 当该域不参与排序域聚合操作时,可设置为false使得不在磁盘上存储Doc value(以列式存储的文档值)以节约磁盘空间。缺省为true
dynamic 该参数控制在对象中检测到的新的域(未在映射中定义)是否加入到域中,当为false或strict时,新域不会加入到映射中。缺省为true
enabled 主要应用于object类型的域,当设置为false,该域不被索引。缺省为true
fielddata 对于text类型的域,如果该参数设置为true,该域的数据在第一次使用时会载入常驻于内存中。缺省为false
format 定义域数据的格式,用于日期类型
ignore_above 定义字符串的有效长度
ignore_malformed 如果设置为true,当字段值与映射定义不一致时,不会抛出错误。缺省为false
index 缺省为true,当设置为false时,该域不被索引,不可被搜索
null_value 定义该域为空值时的格式,如使用“NULL”这样的字符串
search_analyzer 定义搜索时的analyzer,可与定义映射时使用的analyzer不同
store 该值设置为true时,当前域的原始值也存储下来(在_source之外)。默认为false

  总结一下:

字段名称 标准中的数据类型定义 ES中对应类型 备注
FileID string(41) type:keyword <br> doc_values:false <br>ignore_above : 41 不参与排序与聚合
InfoKind int type: integer<br>coerce: false
Source string(2) type:keyword<br> ignore_above : 2
FileName string(0..256) type:keyword<br>ignore_above : 256
StoragePath string(256) type:keyword<br>doc_values:false<br>ignore_above : 256 不参与排序与聚合
FileHash string(32) type:keyword<br>doc_values:false<br> ignore_above : 32 不参与排序与聚合
FileFormat string(32) type:keyword<br>ignore_above : 32
Title string(128) type:keyword <br>ignore_above : 128
SecurityLevel String(1) type:keyword<br> ignore_above : 1
SubmiterName string(0..50) type:keyword <br>ignore_above : 50
SubmiterOrg string(0..100) type:keyword <br>ignore_above : 100
EntryTime dateTime type: date <br>format:yyyyMMddHHmmss 格式为:YYYYMMDDhhmmss
FileSize int type: integer <br> coerce: false

5.4. File对象的映射定义

  我们使用如下命令在ES中创建索引file(注意这里的index.mapping.coerce被设置为false):

curl -iXPUT 'localhost:9200/file?pretty' -H "Content-type: application/json" -d' 
{
  "settings": {
     "number_of_shards":3,
     "number_of_replicas":1,
     "index.mapping.coerce": false
  }
}
'

  使用如下命令修改file索引的映射:

curl -iXPUT 'localhost:9200/file/_mapping/object?pretty' -H "Content-type: application/json" -d'
{
    "properties": {
        "FileObject": {
            "properties": {
                "FileID": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 41
                },
                "InfoKind": {
                    "type": "integer",
                    "coerce": false
                },
                "Source": {
                    "type": "keyword",
                    "ignore_above": 2
                },
                "FileName": {
                    "type": "keyword",
                    "ignore_above": 256
                },
                "StoragePath": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 256
                },
                "FileHash": {
                    "type": "keyword",
                    "doc_values": false,
                    "ignore_above": 32
                },
                "FileFormat": {
                    "type": "keyword",
                    "ignore_above": 32
                },
                "Title": {
                    "type": "keyword",
                    "ignore_above": 128
                },
                "SecurityLevel": {
                    "type": "keyword",
                    "ignore_above": 1
                },
                "SubmiterName": {
                    "type": "keyword",
                    "ignore_above": 50
                },
                "SubmiterOrg": {
                    "type": "keyword",
                    "ignore_above": 100
                },
                "EntryTime": {
                    "type": "date",
                    "format": "yyyyMMddHHmmss"
                },
                "FileSize": {
                    "type": "integer",
                    "coerce": false
                }
            }
        }
    }
}
'

  使用如下命令查看file的映射信息:

curl -iXGET 'localhost:9200/file/_mapping?pretty'

  可以看到返回的映射信息:

{
  "file" : {
    "mappings" : {
      "object" : {
        "properties" : {
          "FileObject" : {
            "properties" : {
              "EntryTime" : {
                "type" : "date",
                "format" : "yyyyMMddHHmmss"
              },
              "FileFormat" : {
                "type" : "keyword",
                "ignore_above" : 32
              },
              "FileHash" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 32
              },
              "FileID" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 41
              },
              "FileName" : {
                "type" : "keyword",
                "ignore_above" : 256
              },
              "FileSize" : {
                "type" : "integer",
                "coerce" : false
              },
              "InfoKind" : {
                "type" : "integer",
                "coerce" : false
              },
              "SecurityLevel" : {
                "type" : "keyword",
                "ignore_above" : 1
              },
              "Source" : {
                "type" : "keyword",
                "ignore_above" : 2
              },
              "StoragePath" : {
                "type" : "keyword",
                "doc_values" : false,
                "ignore_above" : 256
              },
              "SubmiterName" : {
                "type" : "keyword",
                "ignore_above" : 50
              },
              "SubmiterOrg" : {
                "type" : "keyword",
                "ignore_above" : 100
              },
              "Title" : {
                "type" : "keyword",
                "ignore_above" : 128
              }
            }
          }
        }
      }
    }
  }
}

  现在我们可以向file索引提交数据对象了,使用如下命令:

curl -iXPOST 'localhost:9200/file/object/31000000001190000138022019021416121100001?pretty'  -H "Content-type: application/json" -d'
{
    "FileObject": {
        "FileID": "31000000001190000138022019021416121100001",
        "InfoKind": 1, 
        "Source": "3",  
        "FileName": "tollgate_3_lane_4_20190214161211.jpg",
        "StoragePath": "/tollgate/3/lane/4/images",
        "FileHash": "38b8c2c1093dd0fec383a9d9ac940515",
        "FileFormat": "Jpeg",
        "Title": "tollgate_3_lane_4_20190214161211",
        "SecurityLevel": "3",
        "SubmiterName": "zhangkai",
        "SubmiterOrg": "pudong",
        "EntryTime": "20190214161214",
        "FileSize": 94208
    }
}
'

5.5. 小结

  视图库中对象的字段不用进行全文检索,也可以使用关系数据库作为存储容器,但需要对JSON数据进行反序列化解析相应字段入库,查询出库时需要将多个字段序列化为JSON数据。固然在编程时可以使用ORM和JSON序列化中间件来完成工作,但在海量请求下,效率会有影响。使用ES可以利用ES的restful接口和JSON存储格式的天然特性以契合规范要求。

  在视图库规范中有一些自定义的约束,这些涉及数据有效性检验的服务应该部署在ES入库之前。在本实例中,更多的是把ES作为一个Nosql数据库使用。

6. 参考文献

  1. https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
  2. Clinton Gormley &Zachary Tong, Elasticsearch: The Definitive Guide,2015
  3. GA/T 1400.3 公安视频图像信息应用系统 第3部分:数据库技术要求,2017
推荐阅读:
  1. elasticsearch 排序 算法
  2. Elasticsearch搜索调优权威指南 (2/3)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

elasticsearch es mapping

上一篇:celery 简单使用

下一篇:haproxy+keepalived实现web集群的高可用性

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》