Parent-Child
-
场景描述
一个
index
中存在多个type
,一个type
里存放的是所有项目,还有一个type
里存放的是所有资产,每个项都有一些自己资产,现在要查询某一个项目下的所有资产 -
分析
每个资产都归属某一个项目里,即资产和项目存在一定的父子关系(归属)
-
解决方法
定义mapping:
# 父文档mapping project: properties: projectName: type: keyword instanceName: type: keyword tags: type: nested properties: TagKey: type: keyword TagValue: type: keyword #子文档mapping asset: _parent: type: project properties: instanceType: type: keyword instanceID: type: keyword tags: type: nested properties: TagKey: type: keyword TagValue: type: keyword
定义mapping之后,父文档插入的时候最好指定有意义的id,尽量避免默认的id。在插入子文档时,需要指定父文档的id
bulk.push({ index: { _index: 'index', _type: 'type', _id: xxxId, parent: parentId, }, }); bulk.push({ //.... });
-
父子文档的查询
父子文档的关系中,可以通过子文查其父文档,也可以通过父文档查其下所有的子文档
- 通过父文档查子文档:
{ //查询yyy属性为yyyValue的文档的所有子文档 query:{ 'has_parent':{ type: 'xx', //xx为父文档所在的typ query:{ match:{ yyy:yyyValue //yyy为父文档的某一属性 } } } } }
- 通过子文档查父文档
{ //找到yyy值为yyyValue的文档的文档 "query": { "has_child": { "type": "xx", //xx为子文档所在的type "query": { match:{ yyy: yyyValue, //yyy为子文档的某一属性 } } } } }
注意!
父文档可以被更新,且无须重建所有子文档
子文档的添加,修改,删除不影响其父文档和其他子文档
如果parent的值改变了,必须删除这个parent下面的所有子文档然后删除本身,最后添加新的父文档,再添加新的子文档,否则parent值改变后,父文档的parent改变了,子的没改变会出现父子不在同一个shard里面,从而导致查询出错。