Elasticsearch 嵌套类型(nested) updat
2018-04-13 本文已影响0人
_吱吱呀呀
映射类型(mapping)
PUT nested_test
{
"settings": {
"number_of_replicas": 0,
"number_of_shards": 1
},
"mappings": {
"article":{
"properties": {
"title":{
"type": "text",
"analyzer": "hanlp"
},
"content":{
"type":"text",
"analyzer": "hanlp"
},
"promission":{
"type": "nested",
"properties": {
"user_name":{
"type": "keyword"
},
"user_id":{
"type": "keyword"
},
"role_name":{
"type": "keyword"
}
}
}
}
}
}
}
导入测试数据
POST nested_test/article/_bulk
{"index":{}}
{"title":"习近平:中国改革开放必然成功,也一定能够成功!","content":"新华网北京4月10日电 习近平说,今天,中国人民完全可以自豪地说,改革开放这场中国的第二次革命,不仅深刻改变了中国,也深刻影响了世界!他指出, 中国改革开放必然成功,也一定能够成功! (据新华社“新华视点”微博)","promission_obj": {"user_name":"MM","user_id":"001","role_name":"QA"}}
{"index":{}}
{"title":"金句来了!速览“习近平的博鳌时间”重要主旨演讲","content":"新华网北京4月10日电 4月10日上午,中国国家主席习近平应邀出席博鳌亚洲论坛2018年年会开幕式并发表重要主旨演讲。","promission_obj":{"user_name":"ZZ","user_id":"005","role_name":"QP"}}
{"index":{}}
{"title":"习近平会见萧万长一行","content":"新华社海南博鳌4月10日电(记者侯丽军 查文晔)中共中央总书记习近平10日上午在海南博鳌会见前来出席博鳌亚洲论坛2018年年会的台湾两岸共同市场基金会荣誉董事长萧万长一行","promission_obj":{"user_name":"GG","user_id":"002","role_name":"QC"}}
{"index":{}}
{"title":"习近平同奥地利总统范德贝伦举行会谈","content":"4月8日,国家主席习近平在北京人民大会堂同奥地利总统范德贝伦举行会谈。这是会谈前,习近平在人民大会堂北大厅为范德贝伦举行欢迎仪式","promission_obj":{"user_name":"JJ","user_id":"003","role_name":"QE"}}
{"index":{}}
{"title":"新华网评:开放成为博鳌深深的青春印记","content":"18年来,博鳌亚洲论坛始终致力于提供高层对话平台,以增进和深化贸易、投资联系,推动建立伙伴关系,加深亚洲跨文化间相互理解。开放,自始至终都是政府、企业和专家学者在论坛反复强调的共识和举措;开放,更是亚洲经济繁荣发展的客观要求和内生动力","promission_obj":{"user_name":"JJ","user_id":"003","role_name":"QE"}}
{"index":{}}
{"title":"农村电商产业为乡村振兴打下坚实基础","content":"新华网北京4月2日电(胡可璐)今年全国两会期间,“乡村振兴”成为热点话题,连日来讨论热度不减。乡村振兴,产业兴旺是重点","promission_obj": {"user_name":"DD","user_id":"004","role_name":"QO"}}
{"index":{}}
{"title":"广西金桔搭上“电商”路 助力当地农民脱贫致富","content":"在广西省融安县,金桔产业已经打出了“桔乡里”这个响当当的网红电商品牌。谈到当前农村电商的发展问题时,柳州市融安县金色桔韵金桔专业合作社电子商务总经理赖园园表示,绿色健康、品质稳定的农产品,健全的物流体系,政府的政策扶持以及当地健全的电子商务体系是农产品电商成功的关键因素。","promission_obj":{"user_name":"MM","user_id":"001","role_name":"QA"}}
查询数据
GET nested_test/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "习近平重要演讲",
"fields": ["title","content"]
}
},
{
"nested": {
"path": "promission",
"query": {
"bool": {
"must": [
{"term": {
"promission.role_name": "QP"
}}
]
}
}
}
}
]
}
}
}
查询结果
如果我想修改嵌套对象promisson_ojb该如何操作?以下几种方法都可以实现:
执行update API
POST nested_test/article/AWK9Bc0xm0GWwboR_ssF/_update
{
"doc":{
"promission_obj":[
{
"user_name": "ZZ",
"user_id": "005",
"role_name": "QP"
},
{
"user_name": "ZL",
"user_id": "009",
"role_name": "QX"
}
]
}
"detect_noop": false
}
使用doc,会自动合并到现有的文档中。detect_noop
属性会检测写入内容是否与现有文档相同,默认为true
,相同就不会写入。false
表示无视是否修改,强制合并到现有的文档。
或者
POST nested_test/article/AWK9Bc0xm0GWwboR_ssF/_update
{
"scripted_upsert":true,
"script":{
"inline":"ctx._source.promission_obj = params.promission2",
"lang":"painless",
"params":{
"promission2":[
{
"user_name": "ZL",
"user_id": "009",
"role_name": "QM"
},
{
"user_name": "ZZ",
"user_id": "005",
"role_name": "QP"
}
]
}
},
"upsert":{}
}
以上两种都是重新写入嵌套数组(不管之前是什么,重新写入一次)不需要讨论某个嵌套对象的删除,修改操作,如果嵌套对象的数量较多,浪费系统资源,影响检索效率。那么我需要针对某一个嵌套对象进行增删改,该如何操作?以下是针对一个对象的操作:
新增
POST nested_test/article/AWK9Bc0xm0GWwboR_ssF/_update
{
"script":{
"inline":"ctx._source.promission_obj.add(params.promission)",
"lang":"painless",
"params":{
"promission":{
"role_name": "QQ",
"user_id": "009",
"user_name": "DM"
}
}
}
}
修改
POST nested_test/article/AWK9Bc0xm0GWwboR_ssF/_update
{
"script": {
"lang": "painless",
"inline": "
int i = 0;
for(LinkedHashMap promission:ctx._source.promission_obj){
if(promission.user_id == params.user_id)
{
ctx._source.promission_obj[i] = params.promission;
}
i++;
}
",
"params": {
"promission": {
"user_name": "ZO",
"user_id": "011",
"role_name": "QA"
}
}
}
删除
POST nested_test/article/AWK9Bc0xm0GWwboR_ssF/_update
{
"script":{
"inline":"
int i=0;
for(LinkedHashMap pm :ctx._source.promission_obj){
if(pm.user_id==params.promission.user_id)
{
ctx._source.promission_obj.remove(i)
}
i++;
}
",
"lang":"painless",
"params":{
"promission":
{
"user_id": "009"
}
}
}
}
笔记
script
添加/移除字段
POST my_index/type/id/_update
{
"script" : "ctx._source.name_of_new_field = \"fieldName\""
}
POST my_index/type/id/_update
{
"script" : "ctx._source.remove(\"fieldName\")"
}
脚本判断:如果tag标签里面有del标记则删除该文档
POST my_index/type/id/_update
{
"script" : {
"inline": "ctx._source.tags.contains(tag) ? ctx.op = \"delete\" : ctx.op = \"none\"",
"params" : {
"tag" : "del"
}
}
}