- 前言
- 一、嵌套类型是什么
- 二、使用步骤
- 1.在索引目标中新增字段
- 2.写入数据
- 3.查询数据
- 4.嵌套字段的内容删除
- 5.嵌套字段的内容新增
- 总结
前言
来了一个新需求,将A索引下的数据,和B索引下的数据做一下关联。百度了一下解决方案 发现使用嵌套的方式比较好 ,所以进行了测试。
基础知识请搜索其他博客。
场景:当需要存储关系对象时 比如 一个博客下有多个评论
主要解决对象关系存储
需要手动指定索引各字段的类型 并指定关系对象为nested类型
注意只能在新建索引时指定好,否则后续不能修改,需要通过删除索引 重建。
嵌套类型是对象数据类型的一个特例,允许对象数组批次独立的进行检索和查询,可以让array类型的对象被独立索引和搜索
二、使用步骤 1.在索引目标中新增字段代码如下(示例):查看已有的文档字段格式
GET 索引名/_mapping
代码如下(示例):新增nested类型的字段
PUT 索引名/_mapping
{
"properties": {
"user_code_info": {
"type": "nested",
"properties": {
"user_id": {
"type": "keyword"
},
"code_type": {
"type": "keyword"
},
"channel": {
"type": "keyword"
}
}
}
}
}
2.写入数据
代码如下(示例):
POST dev_gb_data_a100_20211103/_doc/nqi0096927ac2f546fba79ee826744cc7a2
{
"id":"nqi0096927ac2f546fba79ee826744cc7a2",
"a100": "GB/T 40249-2021",
"user_code_info": [
{
"code_type": "1",
"user_id": "nqi_1",
"channel": "nqi"
},
{
"code_type": "1",
"user_id": "nqi_2",
"channel": "nqi"
},
{
"code_type": "2",
"user_id": "nqi_1",
"channel": "nqi"
},
{
"code_type": "2",
"user_id": "nqi_2",
"channel": "nqi"
},
{
"code_type": "3",
"user_id": "nqi_1",
"channel": "nqi"
},
{
"code_type": "3",
"user_id": "nqi_2",
"channel": "nqi"
}
]
}
3.查询数据
(1)根据文档id查询:
GET 索引名/_doc/nqi0096927ac2f546fba79ee826744cc7a2
(2)根据过滤条件查询,嵌套字段返回全部数据:
GET 索引名/_search
{
"query": {
"nested": {
"path": "user_code_info",
"query": {
"bool": {
"must": [
{"terms": {
"user_code_info.code_type": [
"1",
"4"
]
}}
]
}
}
}
}
}
(3)网上的一个案例,会影响到算分:
{
"query": {
"nested": {
"path": "comments",
"score_mode": "max",
"query": {
"bool": {
"must": [
{
"term": {
"comments.age": 31
}
},
{
"term": {
"comments.name": "alice"
}
}
]
}
}
}
}
}
score_mode:表示嵌套文档的最高得分纳入到根文档的计算之中。
(3)根据过滤条件查询,嵌套字段返回匹配到的数据:
GET dev_gb_data_a100_20211103/_search
{ "_source": {
"includes": [
"*"
],
"excludes": [
"user_code_info"
]
},
"query": {
"nested": {
"path": "user_code_info",
"query": {
"bool": {
"must": [
{"terms": {
"user_code_info.code_type": [
"1"
]
}}
]
}
},
"inner_hits": {}
}
}
}
4.嵌套字段的内容删除
POST 索引名称/_doc/子文档id/_update
{
"script": {
"lang": "painless",
"source": "ctx._source.user_code_info.removeIf(it -> it.user_id == 'nqi_2' && it.code_type == '1' && it.channel == 'nqi' );"
}
}
5.嵌套字段的内容新增
(一)单个新增的两种方式
POST 索引名/_doc/子文档id/_update
{
"script": {
"lang": "painless",
"source": "if(!ctx._source.user_code_info.contains(params.tag) && ctx._source.user_code_info != null ){ctx._source.user_code_info.add(params.tag)}else if(ctx._source.user_code_info == null){ctx._source.user_code_info=[params.tag]}",
"params": {
"tag": {
"code_type" : "2",
"user_id" : "nqi_3",
"channel" : "nqi"
}
}
}
}
# 新增
POST 索引/_doc/子文档id/_update
{
"script": {
"lang": "painless",
"source": "if(!ctx._source.user_code_info.contains(params) && ctx._source.user_code_info != null ){ctx._source.user_code_info.add(params)}else if(ctx._source.user_code_info == null){ctx._source.user_code_info=[params]}",
"params":{
"code_type" : "2",
"user_id" : "nqi_4",
"channel" : "nqi"
}
}
}
说明:为es中嵌套字段增量更新数据。其中,要对es记录中的字段进行判空,如果为空,则赋值新增数据,如果不为空且记录中不含新增数据,则追加。
注:如果不对字段判空,直接追加的话,会报错。
(二) 批量新增 ,待补充



