元字段是ES为每一个文档配置的内置字段, 主要用于ES内部相关操做.web
_index
标注document属于哪一个index, 是一个虚拟字段, 不会被添加到Lucene索引中.json
将相似的文档 (也就是具备相同field的文档) 存放到同一个index中, 是一种良好的数据建模思想.
提供大量查询的index, 最好不要同时提供大量的统计、聚合等操做——经过把特定的index路由到指定的shard上, 便于系统的优化.bash
注意: 索引名称必须是小写的字母, 不能如下划线"_"开头, 不能包含逗号 ",".数据结构
在term或者terms查询, 聚合、脚本以及排序时, 能够访问_index
字段的值.app
在多个索引中执行查询时, 能够经过添加查询子句来关联特定的索引文档, 使用示例——同时查询多种index:less
GET website,book_shop/_search { "query": { "terms": { // 查询_index是website和book_shop的文档 "_index": [ "website", "book_shop"] } }, "aggs": { "indices": { // 对_index字段进行聚合操做 "terms": { "field": "_index", "size": 10 } } }, "sort": { // 对_index字段进行排序操做 "_index": { "order": "asc" } }, "script_fields": { // 使用脚本, 显示_index字段 "index_name": { "script": { "lang": "painless", "source": "doc['_index']" } } } }
_uid
是_type
和_id
的组合, 形式为{type}#{id}
. 能够用于查询、聚合、脚本和排序.elasticsearch
(1) 添加文档:ide
PUT website/blog/4 { "text": "blog with ID 4" } PUT website/blog/5?refresh=true { "text": "blog with ID 5" }
(2) 检索文档:post
说明: 对
_uid
字段的访问API已通过期, 须要使用_id
替换.#! Deprecation: Fielddata access on the _uid field is deprecated, use _id instead
GET website/_search { "query": { "terms": { // 经过_uid查询_type和_id的复合字段 "_uid": ["blog#4", "blog#5"] } }, "aggs": { "uid_aggs": { "terms": { // 这里经过_uid聚合的操做已通过期 "field": "_id", "size": 10 } } }, "sort": { // 这里经过_uid排序的操做已通过期 "_id": { "order": "desc"} }, "script_fields": { "uid_script": { "script": { // 这里对_uid的脚本操做已通过期 "lang": "painless", "source": "doc['_id']" } } } }
_type
元字段用来标注document属于哪一个类型, 也被称做映射类型.
注意: type的名称能够是大写或小写字母, 但不能如下划线"_"开头, 不能包含逗号",".
在Elasticsearch 6.0以前的版本中, 一个index可能会被划分为多个type, 例如: 商品中有电子商品, 服装商品, 生鲜商品...
但在Elasticsearch 6.0以后, 一个index只能包含一个type, 不然将出现错误.
每个索引文档都包含_type
和_id
字段, _type
字段的目的是经过类型名加快搜索速度.
_type
字段能够在查询、聚合、排序以及脚本中访问到.
关于type的底层数据结构, 可参见ES XX - Elasticsearch对索引类型(_type)的处理方式.
_id
表明document的惟一标识, 与_index
和_type
一块儿, 惟一标识和定位一个document.
注意: 能够手动指定document的id(
PUT index/type/id
), 也能够不指定, Elasticsearch在添加文档时会自动为其建立id.
能够在查询、脚本中访问, 查询示例:
GET website/_search { "query": { "terms": {"_id" : ["1", "2"]} }, "aggs": { "id_aggs": { "terms": { "field": "_id", "size": 10 } } }, "script_fields": { "id_script": { "script": { "lang": "painless", "source": "doc['_id']" } } } }
文档的原始JSON内容将索引到_source
字段中, 该字段自己不创建索引, 可是会被存储.
搜索文档时默认返回该字段及其内容, 但没法用于搜索.
_source
功能默认是开启的, 它会产生额外的存储开销, 能够关闭:
PUT website { "mappings": { "blog": { "_source": {"enabled": false} } } } // 或者: PUT website/_mapping/blog { "_source": {"enabled": false} }
注意: 必须在建立索引时关闭, 建立以后不容许修改, 不然将会发生以下错误:
{ "error": { "root_cause": [ { "type": "resource_already_exists_exception", "reason": "index [website/zIUdhInBQsOUi_4Tt2SSkQ] already exists", "index_uuid": "zIUdhInBQsOUi_4Tt2SSkQ", "index": "website" } ], "type": "resource_already_exists_exception", "reason": "index [website/zIUdhInBQsOUi_4Tt2SSkQ] already exists", "index_uuid": "zIUdhInBQsOUi_4Tt2SSkQ", "index": "website" }, "status": 400 }
_source功能被禁止, 将形成大量功能没法使用:
partial update 功能基于_source实现;
hilight 高亮显示功能基于_source实现;
reindex 重建索引功能基于_source实现, 不须要从其余外部存储中获取数据, 再index;
基于_source定制返回field;
调试query时更容易, 由于能够很直观地看到_source内容……
能够在建立index时, 在mapping中经过includes/excludes
参数来减小_source
字段的内容:
PUT logs { "mappings": { "event": { "_source": { "includes": ["*.count", "meta.*"], // 包含的字段 "excludes": ["meta.desc", "meta.other.*"] // 不包含的字段 } } } }
移除的字段不会被存储在_source中, 但仍然能够搜索到这些字段.
能够在检索时, 禁止返回原始内容:
GET website/blog/1?_source=false
若是只想获取_source
的部份内容, 可使用_source_includes
或_source_excludes
参数:
GET website/blog/1?_source_includes=title,content GET website/blog/1?_source_excludes=post_date,author_id
Elasticsearch 6.0以前的版本中: 使用
_source_include
和_source_exclude
用来指定检索的结果中是否包含_source
中的某个字段;
Elasticsearch 6.0以后的版本中: 相关的API修改成:_source_includes
和_source_excludes
——多加了s
.
记录_source
字段占用的字节数, 由插件mapper-size提供.
(1) ES 6.0以后的方法:
在Elasticsearch 6.0版本中, _all
字段已经被禁用了. 若要开启, 官方建议是:
"Enabling [_all] is disabled in 6.0. As a replacement, you can use [copy_to] on mapping fields to create your own catch all field."
——大体意思是:_all
已经不容许使用了, 做为替换, 咱们可使用copy_to
关键字来建立须要获取的全部字段的内容.
copy_to
的使用方法以下:
PUT logs { "mappings": { "event": { "properties": { "event_id": { "type": "text", "copy_to": {"enabled": true} }, "event_desc": { "type": "text", "copy_to": {"enabled": true}, "analyzer": "english" }, "time": { "type": "date", "copy_to": {"enabled": true}, "format": "strict_date_optional_time||epoch_millis" } } } } }
(2) ES 6.0之前的方法:
在Elasticsearch 6.0以前, _all
字段的使用方式以下:
_all
字段包含1个文档的所有field的内容: 用一个大字符串关联其余全部字段的值, 用空格做为分隔符.
_all
字段能够被分析和索引, 但不会被存储 —— 默认的搜索field.
经过_all
字段能够对文档的值进行搜索而没必要知道相关的字段名.
_all
字段丢失了长字段(低相关性)和短字段(高相关性)之间的区别 —— 在相关性搜索要求比较高的时候, 应该明确指出要查询的字段.
① **_all字段须要额外的处理器周期, 且耗费更多的磁盘空间, 若不须要, 建议禁用此功能:**
PUT website/_mapping/blog { "_all": {"enabled": false} }
② 或 在field中设置include_in_all
—— 是否要将field的值包含在_all
中:
PUT website/_mapping/blog { "properties": { "test_field": { "type": "text", "include_in_all": false } } }
该字段能够用在查询、聚合以及脚本中 —— 用于查找指定字段的值非空的文档是否存在.
使用示例:
GET website/_search { "query": { "terms": {"_field_names": ["content"]} } }
(1) 建立映射:
PUT store { "mappings": { "book": {}, "it_book": { "_parent": {"type": "book"} // 指定其父类 } } }
(2) 插入父文档:
PUT store/book/1 { "desc": "this is parent book"}
(3) 插入子文档, 并指出其父文档:
PUT store/it_book/2?parent=1 { "desc": "this is child it_book"}
(4) 父子文档的限制:
① 父type和子type必须不一样.
② _parent的type的值只能是不存在的类型 —— 一个type被建立后就不能称为父类型了.
(5) 其余说明:
父子文档必须索引在同一个分片上:
① parent的编号用于子文档的路由值, 确保子文档被索引到父文档所在的分片中.
② 查询、更新、删除子文档时, 也须要提供相同的parent值.
用于将文档路由到指定的分片上. 经过以下公式将文档路由到特定的分片:
shard_num = hash(_routing) % num_primary_shards
若是不指定_routing
的值, 默认使用文档的_id
字段. 若是存在父文档则使用其_parent
的编号.
能够经过为某些文档都指定相同的路由值, 来实现对这些文档的自定义路由功能:
// 此文档使用'user_5220'做为其路由值, 在查询、更新、删除时一样须要提供此路由值 PUT website/blog/1?routing=user_5220 { "title": "xxx" }
_routing
字段能够在查询、聚合、脚本以及排序的时候访问. 好比直接指定路由值来搜索相关的文档:
GET website/_search { "query": { "terms": {"_routing": [ "user_5220" ] } } }
_meta - 应用特定的元字段: 每一个type均可以拥有自定义的元数据 —— ES并不会使用, 但能够用来存储应用程序的特定信息.
使用示例:
PUT website { "mappings": { "user": { "_meta": { "class": "com.healchow.website.pojo.User", "version": {"min": "1.0", "max": "1.3"} } } } }
参考资料
版权声明
做者: 马瘦风
出处: 博客园 马瘦风的博客
您的支持是对博主的极大鼓励, 感谢您的阅读.
本文版权归博主全部, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文连接, 不然博主保留追究相关人员法律责任的权利.