elasticsearch 嵌套对象之嵌套类型
nested
类型是一种特殊的对象object
数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询。
1. 对象数组如何扁平化
内部对象object
字段的数组不能像我们所期望的那样工作。 Lucene没有内部对象的概念,所以Elasticsearch将对象层次结构扁平化为一个字段名称和值的简单列表。 例如,以下文件:
curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
'
说明
user
字段被动态的添加为object
类型的字段。
在内部其转换成一个看起来像下面这样的文档:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
user.first
和user.last
字段被扁平化为多值字段,并且alice
和white
之间的关联已经丢失。 本文档将错误地匹配user.first
为alice
和user.last
为smith
的查询:
curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
'
2. 对对象数组使用嵌套字段
如果需要索引对象数组并维护数组中每个对象的独立性,则应使用nested
数据类型而不是object
数据类型。 在内部,嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引,这意味着每个嵌套对象都可以使用嵌套查询nested query
独立于其他对象进行查询:
curl -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
"mappings": {
"my_type": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
}
'
curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -H 'Content-Type: application/json' -d'
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
'
说明
user
字段映射为nested
类型,而不是默认的object
类型
curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
'
说明
此查询得不到匹配,是因为Alice
和Smith
不在同一个嵌套对象中。
curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }}
]
}
},
"inner_hits": {
"highlight": {
"fields": {
"user.first": {}
}
}
}
}
}
}
'
说明
此查询得到匹配,是因为Alice
和White
位于同一个嵌套对象中。
inner_hits
允许我们突出显示匹配的嵌套文档。
输出
{
"took": 151,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.3862944,
"hits": [
{
"_index": "indextest010",
"_type": "my_type",
"_id": "1",
"_score": 1.3862944,
"_source": {
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
},
"inner_hits": {
"user": {
"hits": {
"total": 1,
"max_score": 1.3862944,
"hits": [
{
"_index": "indextest010",
"_type": "my_type",
"_id": "1",
"_nested": {
"field": "user",
"offset": 1
},
"_score": 1.3862944,
"_source": {
"first": "Alice",
"last": "White"
},
"highlight": {
"user.first": [
"<em>Alice</em>"
]
}
}
]
}
}
}
}
]
}
}
嵌套文档可以:
- 使用nested查询进行查询
- 使用nested和reverse_nested聚合进行分析
- 使用nested排序进行排序
- 使用nested inner hits进行检索与突出显示
3. 嵌套字段参数
嵌套字段接受以下参数:
参数 | 描述 |
---|---|
dynamic | 是否将新属性动态添加到现有的嵌套对象。共有true (默认),false 和strict 三种参数。 |
include_in_all | Sets the default include_in_all value for all the properties within the nested object. Nested documents do not have their own _all field. Instead, values are added to the _all field of the main “root” document. |
properties | 嵌套对象中的字段,可以是任何数据类型,包括嵌套。新的属性可能会添加到现有的嵌套对象。 |
备注
类型映射(type mapping
)、对象字段和嵌套字段包含的子字段,称之为属性properties
。这些属性可以为任意数据类型,包括object
和 nested
。属性可以通过以下方式加入:
- 当在创建索引时显式定义他们。
- 当使用
PUT mapping API
添加或更新映射类型时显式地定义他们。 - 当索引包含新字段的文档时动态的加入。
重要
由于嵌套文档作为单独的文档进行索引,因此只能在nested
查询,nested
/reverse_nested
聚合或者 nested inner hits 的范围内进行访问。
For instance, if a string field within a nested document has index_options set to offsets to allow use of the postings highlighter, these offsets will not be available during the main highlighting phase. Instead, highlighting needs to be performed via nested inner hits.
4. 限制嵌套字段的个数
索引一个拥有100个嵌套字段的文档,相当于索引了101个文档,因为每一个嵌套文档都被索引为一个独立的文档.为了防止不明确的映射,每个索引可以定义的嵌套字段的数量已被限制为50个。 具体请参阅 Settings to prevent mappings explosion
原文:https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html#nested-params
补充更新2018年7月30日
多嵌套查询方式:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": [
"ajxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"ajxx.ajmc": "案件名称"
}
},
{
"range": {
"ajxx.sasj": {
"gte": "2015-01-01 12:10:10",
"lte": "2015-01-01 12:10:40"
}
}
}
]
}
}
}
},
{
"nested": {
"path": [
"rqxx"
],
"query": {
"bool": {
"must": [
{
"range": {
"rqxx.rqsj": {
"gte": "2015-01-01 12:10:10",
"lte": "2015-01-01 12:10:40"
}
}
}
]
}
}
}
}
]
}
}
}
2018年7月31日 16:59:14更新
全文及条件检索
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": [
"ajxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"ajxx.ajzt": "破案"
}
},
{
"range": {
"ajxx.sasj": {
"gte": "2017-01-01 12:10:10",
"lte": "2017-01-02 12:10:40"
}
}
}
],
"should": [
{
"bool": {
"must": [
{
"query_string": {
"query": "20170316盗窃案"
}
}
]
}
}
]
}
}
}
}
]
}
}
}
多嵌套且全文检索
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": [
"ajxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"ajxx.ajmc": "案件名称"
}
},
{
"range": {
"ajxx.sasj": {
"gte": "2015-01-01 12:10:10",
"lte": "2015-01-01 12:10:40"
}
}
},
{
"query_string": {
"query": "物品状态"
}
}
]
}
}
}
},
{
"nested": {
"path": [
"rqxx"
],
"query": {
"bool": {
"must": [
{
"range": {
"rqxx.rqsj": {
"gte": "2015-01-01 12:10:10",
"lte": "2015-01-01 12:10:40"
}
}
}
]
}
}
}
}
]
}
}
}
最后精简
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": [
"ajxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"ajxx.ajzt": "破案"
}
},
{
"range": {
"ajxx.sasj": {
"gte": "2017-01-01 12:10:10",
"lte": "2017-01-02 12:10:40"
}
}
}
],
"should": [
{
"query_string": {
"query": "20170316盗窃案"
}
}
]
}
}
}
}
]
}
}
}
查询字段名称的模糊匹配编辑
字段名称可以用模糊匹配的方式给出:任何与模糊模式正则匹配的字段都会被包括在搜索条件中
{
"multi_match": {
"query": "结果",
"fields": ["*","*_title"]
}
}
当这些子字段出现数值类型的时候,就会报异常了,解决方法是加入lenient
字段
{
"type": "parse_exception",
"reason": "failed to parse date field [XXX] with format [yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis]"
}
{
"multi_match": {
"query": "结果",
"lenient": "true",
"fields": ["*"]
}
}
利用multi_match嵌套全文检索
"include_in_parent":true,
"include_in_root":true,
{
"query": {
"bool": {
"must": [
{
"match": {
"ajztmc": "立案"
}
},
{
"match": {
"ajlxmc": "刑事"
}
},
{
"range": {
"lasj": {
"gte": "2015-01-01 12:10:10",
"lte": "2016-01-01 12:10:40"
}
}
},
{
"nested": {
"path": [
"rqxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"rqxx.baqmc": "办案区名称"
}
}
]
}
}
}
},
{
"nested": {
"path": [
"saryxx"
],
"query": {
"bool": {
"must": [
{
"match": {
"saryxx.rylxmc": "嫌疑人"
}
},
{
"match": {
"saryxx.ryxb": "女"
}
}
]
}
}
}
},
{
"nested": {
"path": [
"wp"
],
"query": {
"bool": {
"must": [
{
"match": {
"wp.wpzlmc": "赃物"
}
},
{
"match": {
"wp.wpztmc": "物品入库"
}
}
]
}
}
}
},
{
"multi_match": {
"query": "男",
"lenient": "true",
"fields": [
"*"
]
}
}
]
}
},
"from": 0,
"size": 100,
"sort": {
"zxxgsj": {
"order": "desc"
}
}
}
参考:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/multi-match-query.html
http://www.bubuko.com/infodetail-2153060.html
https://www.cnblogs.com/huangfox/p/3544883.html
elasticsearch 嵌套对象之嵌套类型的更多相关文章
- elasticsearch嵌套对象的映射
在es中,我们有时候可能需要映射,{ "field" : "xx" , "field01" : [] }这样格式的嵌套对象,默认情况下es会 ...
- elasticsearch 嵌套对象使用Multi Match Query、query_string全文检索设置
参考: https://www.elastic.co/guide/en/elasticsearch/reference/1.7/mapping-nested-type.html https://sta ...
- Elasticsearch 7.x Nested 嵌套类型查询 | ES 干货
一.什么是 ES Nested 嵌套 Elasticsearch 有很多数据类型,大致如下: 基本数据类型: string 类型.ES 7.x 中,string 类型会升级为:text 和 keywo ...
- AutoMapper 创建嵌套对象映射(原创)
之前在做DTO转换时,用到AutoMapper.但DTO的层次太深了,无奈官方没针对嵌套类型提供好的解决方案,于是自己实现了一下: 思路:采用递归和反射很好的避免手工创建嵌套对象的映射. 第一个版本, ...
- js嵌套对象相等比较的一种方法 (原创)
做前端开发经常会遇到比较js对象是否相等的情况, 或者说其它问题往往会归结到这个问题上来:比如对象数组的去重复. 网上看到过很多例子, 但是基本上都是那种比较简单的对象结构, 而复杂的对象结构,比如对 ...
- ElasticSearch 嵌套映射和过滤器及查询
ElasticSearch - 嵌套映射和过滤器 Because nested objects are indexed as separate hidden documents, we can’t q ...
- 让jquery easyui datagrid列支持绑定嵌套对象
嵌套对象是指返回的json数据,是对象的某个属性自带有属性.而我们恰恰又需要这个属性,默认情况下easyui的datagrid是不支持绑定嵌套对象的.比如:datagrid的field属性只能为fie ...
- WinForm 绑定到嵌套对象上的属性
WinFrom 绑定到嵌套对象上的属性 关键字: Windows Forms, DataBindings, Nested Class, 嵌套类 在 WinForm 中很早就已经支持数据绑定, 使用数据 ...
- 转载 -- jquery easyui datagrid 动态表头 + 嵌套对象属性展示
代码功能: 1.datagrid 的表头由后台生成,可以配置在数据库 2.datagrid 的列绑定数据 支撑嵌套对象 $(function() { var columns = new Array() ...
随机推荐
- MySQL--11 备份的原因
目录 一.备份的原因 二.备份的类型 三.备份的方式 四.备份策略 五.备份工具 六.企业故障恢复案例 1.模拟环境 2.模拟恢复数据过程: 一.备份的原因 运维工作的核心简单概括就两件事: 1)第一 ...
- overload和override的含义和区别
重载(overload)和重写/覆盖(override)是Java多态性的不同表现形式. 重载(overload) (1) 重载是通过不同的方法参数来区分的,如不同的参数个数.顺序.类型. (2) 不 ...
- Axis2 客户端调用 设置超时时间
我用的是axis2-1.6.2版本.请看下面的客户端代码: import org.apache.axis2.client.Options; import com.ctis.ta.service.imp ...
- [CSS布局]简单的CSS三列布局
前言 公司终于可以上外网了,近期在搞RN的东西,暂时脑子有点晕,等过段时间再来写点总结.倒是最近有个新学前端的同学经常会问一些基础知识,工作空闲写了小Demo给他看,全是很基础的知识,纯粹是顺便记录在 ...
- Center os 用户环境变量
vi ~/.bash_profile进入用户环境变量设置 export JAVA_HOME=/usr/java/jdk1.7.0_76export JAVA_BIN=$JAVA_HOME/binexp ...
- 苹果的AR赌注仍然有很多需要证明的
苹果公司为开发者主题发布会做准备,其中一个更大的公告很可能是其增强现实平台的新变化.自从去年宣布ARKit以来,这家科技巨头几乎对其对AR的潜力抱有信心. 在很多讨论背后,人们都相信技术的实用性,但在 ...
- 05.配置为开发模式、配置静态资源locations、自定义消息转化器、FastJson
配置为开发模式,代码做了修改,不用重新运行 idea需要该配置,mac测试无效 <dependency> <groupId>org.springframework</gr ...
- java 比较两个日期大小(2) 用before(), after()
调试代码,我就不整理了,记下after() before() 觉得这张图好美,从人家的博客上截的,找不到链接了
- Hadoop编程调用HDFS(PYTHON)
1.运行环境 开发工具:PyCharm Python 版本:3.5 Hadoop环境: Cloudera QuickStart 2.GITHUB地址 https://github.com/nbfujx ...
- 谷歌SEO和百度SEO的区别
远程桌面连接 一直有一个现象:关于谷歌优化或只是以谷歌为例谈SEO观点或技术时,经常有读者说,不适用于百度,希望多看到关于百度SEO的帖子上一篇利用规范的标签在谷歌排名中陷害竞争对手的帖子,就有好 ...