设为首页 收藏本站
查看: 773|回复: 0

[经验分享] elasticsearch文档-字段的mapping

[复制链接]

尚未签到

发表于 2017-5-21 07:08:21 | 显示全部楼层 |阅读模式
elasticsearch文档-字段的mapping
mapping
  Mapping是指定义如何将document映射到搜索引擎的过程,比如一个字段是否可以查询以及如何分词等,一个索引可以存储含有不同"mapping types"的documents,ES允许每个mapping type关联多个mapping定义。
  显式声明的mapping是定义在index/type级别, 默认不需要显式的定义mapping, 当新的type或者field引入时,ES会自动创建并且注册有合理的默认值的mapping(毫无性能压力), 只有要覆盖默认值时才必须要提供mapping定义。
  mapping types
  Mapping types是将索引里的documents按逻辑分组的方式, 类似数据中的表, 虽然不同的types之间有些区别, 但他们并不是完全分开的(说到底还是存在相同的Lucene索引里)。
  强烈建议跨types的同名field有相同的类型定义以及相同的mapping特征(比如analysis的设置), 这在通过type前缀(my_type.my_field)来选择字段时非常有效, 但这也不一定, 有些地方就不起作用(比如字段的聚合faceting)。
  实际上在实践中这个限制从来不是问题, field名通常表明了该field的类型(例如"first_name"总是一个字符串)。 还要注意, 这不适用于跨索引的情况。
  mapping api
  要创建mapping, 需要用到Put Mapping接口, 或者可以在调用create index接口时附带mapping的定义。
  global settings
  全局设置index.mapping.ignore_malformed可以在索引级别上设置是否忽略异常内容(异常内容的一个例子是尝试将字符串类型的值作为数字类型索引), 这个设置是跨mapping types的全局设置。
fields
  每一个ampping都有一些关联的字段来控制如何索引的document的元数据(例如_all)。
_uid
  每个索引的document会关联一个id和一个type, 内部的_uid字段将type和id组合起来作为document的唯一标示(这意味着不同的type可以有相同的id, 组合起来仍然是唯一的)。
  在执行基于type的过滤时, 如果_type字段没有被索引,会自动使用_uid字段, 并且不需要_id字段被索引。

  • 附_uid的java源代码

  • publicstaticfinalbyte DELIMITER_BYTE =0x23;

  • publicstaticvoid createUidAsBytes(BytesRef type,BytesRef id,BytesRef spare){
  •     spare.copyBytes(type);
  •     spare.append(DELIMITER_BYTES);
  •     spare.append(id);
  • }
_id
  每个索引的document会关联一个id和一个type, _id字段就是用来索引并且存储(可能)id的,默认是不索引(not indexed)并且不存储的(not stored)。
  注意, 即使_id是不索引的, 相关的接口仍然起作用(他们会用_uid字段), 比如用term, terms或者prefix来根据ids过滤(包括用ids来查询/过滤)。
  _id字段也可以启用索引或者存储, 配置如下:

  • {
  • "tweet":{
  • "_id":{"index":"not_analyzed","store":"yes"}
  • }
  • }
  为了维护向后兼容性, 当升级到0.16时可以在节点级别设置index.mapping._id.indexed为true来确保id能被索引, 尽管不建议索引id。
  可以设置_id的path属性来从源文档中提取id, 例如下面的mapping:

  • {
  • "tweet":{
  • "_id":{
  • "path":"post_id"
  • }
  • }
  • }
  如果提交下面的数据

  • {
  • "message":"You know, for Search",
  • "post_id":"1"
  • }
  1会提取出来作为id。
  因为要提取id来决定在哪一个shard执行索引,需要在索引时做额外的解析。
_type
  每个索引的document会关联一个id和一个type, type在索引时会自动赋给_type字段, 默认_type字段是需要索引的(但不analyzed)并且不存储的, 这就意味着_type字段是可查询的。
  _type字段也可以设置为stored, 例如:

  • {
  • "tweet":{
  • "_type":{"store":"yes"}
  • }
  • }
  _type字段也可以设置为不索引, 并且此时所有用到_type字段的接口仍然能用。

  • {
  • "tweet":{
  • "_type":{"index":"no"}
  • }
  • }
_source
  _source是一个自动生成的字段, 用来存储实际提交的JSON数据, 他是不索引的(不可搜索), 只是用来存储。 在执行"fetch"类的请求时, 比如get或者search, _source字段默认也会返回。
  尽管_source非常有用, 但它确实会占用索引的存储空间, 所以也可以禁用。 比如:

  • {
  • "tweet":{
  • "_source":{"enabled":false}
  • }
  • }
  compression
  从0.90开始, 所有存储的字段(包括_source)总是被压缩的。
  0.90之前:
  如果要将source字段存储在索引中的话,启用压缩(LZF)会显著减少索引的大小, 还可能提升性能(解压缩比从磁盘上加载一个比较大的source的性能要好)。 代码需要特别注意,只有需要的时候才执行解压缩, 例如直接将数据解压缩到REST的结果流。
  要启用压缩的话, 需要将compress选项设置为true, 默认设置是false。 注意可以在已经存在的索引上修改,ES支持压缩和未压缩的数据混合存放。
  另外,compress_threshold可以控制压缩source的时机,可以设置为表示字节大小的值(比如100b, 10kb)。 注意compress应该设置为true。
  includes / excludes
  可以用path属性来包含/排除source中要存储的字段,支持*通配符,例如:

  • {
  • "my_type":{
  • "_source":{
  • "includes":["path1.*","path2.*"],
  • "excludes":["pat3.*"]
  • }
  • }
  • }
_all
  _all字段的设计目的是用来包罗文档的一个或多个字段, 这对一些特定的查询非常有用, 比如我们要查询文档的内容, 但是不确定要具体查询哪一个字段, 这会占用额外的cpu和索引容量。
  _all字段可以完全禁止掉, field mapping和object mapping可以声明这个字段是否放到_all中。 默认所有的字段都包含在_all中。
  禁用_all字段时, 推荐为index.query.default_field设置一个值(例如, 你的数据有一个"message"字段来存储主要的内容, 就设置为message)。
  _all字段一个很有用的特征是可以把字段的boost等级考虑进去, 假设title字段的boost等级比content字段高, _all中的title值也比_all中的content值等级高。
  以下是一个配置的例子:

  • {
  • "person":{
  • "_all":{"enabled":true},
  • "properties":{
  • "name":{
  • "type":"object",
  • "dynamic":false,
  • "properties":{
  • "first":{"type":"string","store":"yes","include_in_all":false},
  • "last":{"type":"string","index":"not_analyzed"}
  • }
  • },
  • "address":{
  • "type":"object",
  • "include_in_all":false,
  • "properties":{
  • "first":{
  • "properties":{
  • "location":{"type":"string","store":"yes","index_name":"firstLocation"}
  • }
  • },
  • "last":{
  • "properties":{
  • "location":{"type":"string"}
  • }
  • }
  • }
  • },
  • "simple1":{"type":"long","include_in_all":true},
  • "simple2":{"type":"long","include_in_all":false}
  • }
  • }
  • }
  在这个例子里, _all字段设置了store, term_vector和analyzer(指定index_analyzer和search_analyzer)。
  highlighting
  任何可以highlighting的字段必须既是stored的,又是_source的一部分,默认_all字段不符合这个条件, 所以它的highlighting不会返回任何数据。
  尽管可以设置_all为stored, 但_all从根本上说是所有字段的集合, 也就是说会存储多余的数据,它做highlighting可能产生怪怪的结果。
_analyzer
  _analyzer mapping可以将document某个字段的值作为索引时所用analyzer的名字,如果一个字段没有显式指定analyzer或者index_analyzer, 索引时就会用这个analyzer。
  下面是配置的例子:

  • {
  • "type1":{
  • "_analyzer":{
  • "path":"my_field"
  • }
  • }
  • }
  上面的配置用my_field字段的值作为analyzer, 比如下面的文档:

  • {
  • "my_field":"whitespace"
  • }
  会让所有没有指定analyzer的字段用whitespace做索引的analyzer。
  path的默认值是_analyzer, 所以可以给_analyzer字段赋值来指定一个analyzer, 如果需要自定义为别的json字段, 需要通过path属性来明确指定。
  默认_analyzer字段是可索引的, 可以在mapping中将index设置为no来禁用。
_boost
  Boosting是增强文档或者字段关联性的过程,字段级别的mapping可以将boost指定为某个字段。 _boost(应用在root object上)可以指定一个字段,这个字段的内容控制文档的boost级别。 例如下面的mapping:

  • {
  • "tweet":{
  • "_boost":{"name":"my_boost","null_value":1.0}
  • }
  • }
  上面的定义指定了一个名为字段my_boost的字段, 如果要索引的JSON文档包括my_boost字段, 字段的值就作为文档的boost值, 比如下面的JSON文档的boost值为2.2:

  • {
  • "my_boost":2.2,
  • "message":"This is a tweet!"
  • }
  (注:name属性默认是_boost)
_parent
  _parent用来定义子类型所关联的父类型, 比如有一个blog类型和一个blog_tag子类型, blog_tag的mapping应该是:

  • {
  • "blog_tag":{
  • "_parent":{
  • "type":"blog"
  • }
  • }
  • }
  _parent默认是stored以及indexed的, 也就是说可以用_parent来查询。
_routing
  routing是索引数据或者需要明确指定路由时routing的设置。
  store / index
  _routing的mapping默认会存储routing的值(store设置为yes), 之所以这么做是为了可以在routing值来自外部而不是document一部分时仍然可以重建索引。
  required
  另一方面, 可以在_routing的mapping中设置required属性为true来将它设置为必需的,这在使用routing功能是非常重要, 因为很多接口会用到它。 如果没有提供routing值(或者不能从document获取)的话,索引操作就不会执行,再比如如果_routing是必须的但是没有提供routing值的话,删除操作就会广播到所有的分片(shards)上。
  path
  routing的值可以在索引时额外提供(并且作为document的一部分存储, 和_source字段存储方式很像), 也可以根据path自动从要索引的document提取, 例如下面的mapping:

  • {
  • "comment":{
  • "_routing":{
  • "required":true,
  • "path":"blog.post_id"
  • }
  • }
  • }
  会使下面的document基于值111222来路由:

  • {
  • "text":"the comment text"
  • "blog":{
  • "post_id":"111222"
  • }
  • }
  注意, 使用path而不是明确提供routing值的话, 索引时需要额外的解析过程(尽管相当快)。
  id uniqueness
  如果自定义_routing的话, 不保证_id在所有分片(shards)的唯一性。 事实上, 如果document的_id相同而_routing值不同的话, 会被分配到不同分片上。
_index
  _index存储一个document属于哪一个索引(index), 该字段默认是禁用的, 如果要启用的话, mapping的定义如下:

  • {
  • "tweet":{
  • "_index":{"enabled":true}
  • }
  • }
_size
  _size字段自动存储原始_source的大小, 默认是禁用的, 要启用的话mapping定义如下:

  • {
  • "tweet":{
  • "_size":{"enabled":true}
  • }
  • }
  如果还要存储的话, 定义如下:

  • {
  • "tweet":{
  • "_size":{"enabled":true,"store":"yes"}
  • }
  • }
_timestamp
  _timestamp字段允许自动索引一个document的时间戳, 它可以在索引请求时提供, 也可以从_source提取,如果没有提供的话会自动设置为document被处理的时间。
  enabled
  _timestamp默认是禁用的, 如果要启用, mapping的定义如下所示:

  • {
  • "tweet":{
  • "_timestamp":{"enabled":true}
  • }
  • }
  store / index
  默认_timestamp字段的store设置为no, index设置为not_analyzed, 它可以当做一个标准的日期字段来查询。
  path
  _timestamp的值可以在索引请求时额外提供, 也可以根据path自动从document中提取, 例如下面的mapping定义:

  • {
  • "tweet":{
  • "_timestamp":{
  • "enabled":true,
  • "path":"post_date"
  • }
  • }
  • }
  提交的数据为

  • {
  • "message":"You know, for Search",
  • "post_date":"2009-11-15T14:12:12"
  • }
  时间戳的值就是2009-11-15T14:12:12。
  注意, 如果用path方式而没有明确提供时间戳的值的话, 索引时需要额外的解析操作(尽管相当快)。
  format
  你可以定义时间戳的格式, 例如:

  • {
  • "tweet":{
  • "_timestamp":{
  • "enabled":true,
  • "path":"post_date",
  • "format":"YYYY-MM-dd"
  • }
  • }
  • }
  注意, 默认的格式是dateOptionalTime, 时间戳的值首先作为数字解析, 如果解析失败的话会尝试用定义的格式解析。
_ttl
  很多documents有过期时间, 可以设置_ttl(time to live)来自动删除过期的documents。
  enabled
  _ttl默认是禁用的, 要启用的话, mapping定义如下:

  • {
  • "tweet":{
  • "_ttl":{"enabled":true}
  • }
  • }
  store / index
  默认_ttl字段的store设置为yes, index设置为not_analyzed, 注意index必须设置为not_analyzed。
  default
  可以为index/type设置默认的_ttl, 比如:

  • {
  • "tweet":{
  • "_ttl":{"enabled":true,"default":"1d"}
  • }
  • }
  这种情况下, 如果你没有明确提供_ttl的值, _source里也没有_ttl的话, 所有的tweets的_ttl会被设置为一天。
  如果你没有指定时间的单位,比如d (days), m (minutes), h (hours), ms (milliseconds), (weeks), 默认把毫秒(milliseconds)作为单位。
  如果没有设置默认值, 也没有提供_ttl的值, document会有无限的_ttl,即永不过期。
  可以用put mapping接口动态更新default的值, 这不会改变已有documents的_ttl, 只会影响新的documents。
  note on documents expiration
  过期的documents会自动定期删除, 可以根据你的需要来设置indices.ttl.interval, 默认是60s。
  删除命令是批量处理的, 可以根据你的需要来设置indices.ttl.bulk_size, 默认是10000。
  注意, 删除是根据版本来的, 如果document在收集过期的documents和执行删除操作的时间间隔之间被修改了, document是不会被删除的。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-379428-1-1.html 上篇帖子: elasticsearch实现联想输入搜索(like操作) 下篇帖子: [Elasticsearch] 分布式搜索
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表