嵌套对象能够表达关系型数据库中一对多关系,同时加强检索能力。下面定义human索引包括cats嵌套对象,定义mapping:web
PUT human { "mappings": { "properties": { "name": { "type": "text" }, "cats": { "type": "nested", "properties": { "colors": { "type": "integer" }, "name": { "type": "text" }, "breed": { "type": "keyword" } } } } } }
Human有name
属性和嵌套对象cats
;cats包括下面三个属性:colors,name,breed
。数据库
下面增长一个文档带有三个cat:api
PUT /human/_doc/1 { "name": "iridakos", "cats": [ { "colors": 1, "name": "Irida", "breed": "European Shorthair" }, { "colors": 2, "name": "Phoebe", "breed": "European" }, { "colors": 3, "name": "Nino", "breed": "Aegean" } ] }
查询文档确认添加:app
GET /human/_doc/1
返回结果:svg
{ "_index" : "human", "_type" : "_doc", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "_source" : { "name" : "iridakos", "cats" : [ { "colors" : 1, "name" : "Irida", "breed" : "European Shorthair" }, { "colors" : 2, "name" : "Phoebe", "breed" : "European" }, { "colors" : 3, "name" : "Nino", "breed" : "Aegean" } ] } }
下面讨论如何对嵌套对象进行添加、修改、删除。code
增长一个嵌套对象Leon
。使用_update
api:xml
POST /human/_update/1 { "script": { "source": "ctx._source.cats.add(params.cat)", "params": { "cat": { "colors": 4, "name": "Leon", "breed": "Persian" } } } }
经过ctx._source.cats
访问嵌套对象,返回collection,执行add
方法增长新的cat。新cat属性经过params传入。对象
咱们如今删除cat集合中删除Nino
:索引
POST /human/_update/1 { "script": { "source": "ctx._source.cats.removeIf(cat -> cat.name == params.cat_name)", "params": { "cat_name": "Nino" } } }
经过ctx._source.cats
返回集合,经过removeIf方法有条件删除条目。removeIf方法参数为Predicate,肯定是否要删除特定条目。predicate在集合中每一个条目上执行,返回值为Boolean,true则删除,咱们示例经过判断name属性使用与参数cat_name
相同。ip
修改全部cat的属性breeds 为 European 修改成 European Shorthair:
POST /human/_update/1 { "script": { "source": "def targets = ctx._source.cats.findAll(cat -> cat.breed == params.current_breed); for(cat in targets) { cat.breed = params.breed }", "params": { "current_breed": "European", "breed": "European Shorthair" } } }
ctx._source.cats
返回集合,在集合上执行findAll
方法选择想要的条目,Predicate参数设定条件。查询内容和修改内容都经过参数传入。
如今使用更加灵活脚本实现更复杂的示例。目标对象须要多个条件进行匹配,更新多个属性。
加入咱们想修改cat属性breed为Persian,colors为3,修改成Aegean和3 。脚本以下:
POST /human/_update/1 { "script": { "source": "def targets = ctx._source.cats.findAll(cat -> { for (condition in params.conditions.entrySet()) { if (cat[condition.getKey()] != condition.getValue()) { return false; } } return true; }); for (cat in targets) { for (change in params.changes.entrySet()) { cat[change.getKey()] = change.getValue() } }", "params": { "conditions": { "breed": "Persian", "colors": 4 }, "changes": { "breed": "Aegean", "colors": 3 } } } }
格式化代码:
def targets = ctx._source.cats.findAll(cat -> { for (condition in params.conditions.entrySet()) { if (cat[condition.getKey()] != condition.getValue()) { return false; } } return true; }); for (cat in targets) { for (change in params.changes.entrySet()) { cat[change.getKey()] = change.getValue() } }
经过params.conditions
参数肯定条件查询目标对象,经过params.changes参数传入修改后的值。
本文介绍Elasticsearch的嵌套对象,经过示例说明如何使用脚本维护嵌套对象。