Elasticsearch脚本更新嵌套类型

  • 数据样例

索引名:nested
类型:doc1

{
    "detail": [
        {
            "name": "美团",
            "nid": 1200
        }
    ],
    "id": 1
}
  • 添加
    POST /nested/doc1/1/_update
{
    "script": {
        "lang": "painless",
        "source": "ctx._source.detail.add(params.data);",
        "params": {
            "data": {
                "name": "百度",
                "nid": 1300
            }
        }
    }
}

# 数据:
{
   "_index": "nested",
    "_type": "doc1",
    "_id": "1",
    "_score": 1.0,
    "_source": {
        "detail": [
            {
                "name": "美团",
                "nid": 1200
            },
            {
                "name": "百度",
                "nid": 1300
            }
        ],
        "id": 1
    }
}
  • 修改
    POST /nested/doc1/1/_update
{
    "script": {
        "lang": "painless",
        "source": "for(e in ctx._source.detail){if (e.name == params.name) {e.nid = params.nid;}}",
        "params": {
        	"name": "百度",
        	"nid": 1500
        }
    }
}
  • 删除

POST /nested/doc1/1/_update

{
    "script": {
        "lang": "painless",
        "source": "ctx._source.detail.removeIf(it -> it.nid ==params.nid);if(ctx._source.detail.length == 0){ctx.op='delete'}",
        "params":{
        	"nid": 1200
        }
    }
}

# 删除后
{
    "_index": "nested",
    "_type": "doc1",
    "_id": "1",
    "_score": 1,
    "_source": {
        "detail": [
            {
                "name": "百度",
                "nid": 1500
            }
        ],
        "id": 1
    }
}

这个脚本先删除detail中nid=1200的元素,然后判断如果detail长度为0则删除这条数据。
如果指定的nid不存在,也会返回200,但数据的版本号+1

  • 查询

GET /nested/doc1/_search

{
    "query": {
        "nested": {
            "path": "detail",
            "query": {
                "term": {
                    "detail.nid": 1500
                }
            },
            "inner_hits": {}  # 返回嵌套查询命中的文档,可像普通查询那样添加from,size,_source等参数
        }
    }
}
  • 使用脚本来获取每条数据中嵌套类型数组的长度
{
    "query": {
        "match_all": {}
    },
    "script_fields": {
        "detail_count": {  # 名称自定义
            "script": {
                "lang": "painless",
                "source": "params['_source']['detail'].length"
            }
        }
    },
    "size": 100
}

params['_source']doc['xxx']的区别:

  • doc仅用于获取简单的(一个键对应一个值)、不分析的字段的值,像嵌套类型、文本类型等是不能用的。因此查询会缓存,速度快,但也意味着更多的内存消耗。
  • params['_source']每次使用都要加载和解析,所以速度慢。

推荐使用doc,不能用再使用params。

注意
脚本中应避免使用硬编码,即使用类似下面的编写方式:
"source": "for(e in ctx._source.detail){if (e.name == '百度') {e.nid = 1500;}}",这将导致脚本每次运行之前都要进行编译解析等工作,应当使用params参数。如果脚本是固定的,可将脚本保存在es中,后续只需要传入脚本id和参数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值