在传统的数据库中,对数据关系的描述有一对一,一对多,多对多的关系。如果我们有关联的数据,一般都会采用添加主键外键的形式来建立数据之间的关系,然后查询的时候通过join的形式来得到我们想要的数据。但是转化到elasticsearch中,我们是如何处理有关系的数据?elasticsearch本身是nosql类型的数据,弱化了对关系模型的支持,如果对关系型的支持,想必肯定会影响elasticsearch的性能。但是我们现实中的数据肯定是有关系的,那么我们就一起来看看elasticsearch是如何处理带有关系的数据?
{
"order_id" : "订单ID",
"order_item" : [
{
"goods_id" : "12345",
"goods_name" : "YSL圣罗兰"
},
{
"goods_id" : "12346",
"goods_name" : "花王纸尿布"
}
]
}
最终elasticsearch会平铺成以下数据,在一个文档中goods_id 和goods_name 没有存在任何关系数据
{
"order_id" : "订单ID",
"order_item.goods_id":["12345","12346"],
"order_item.goods_name":["YSL圣罗兰","花王纸尿布"]
}
elasticsearch的每个field都是支持多值存储,在上面的json中我们看着像order和orderItem一对多的结构,其实最终的存储是每个字段存储多值。
{
"order_id" : "订单ID",
"order_item" : [
{
"goods_id" : "12345",
"goods_name" : "YSL圣罗兰"
},
{
"goods_id" : "12346",
"goods_name" : "花王纸尿布"
}
]
}
在elasticsearch中会存储成3个文档,3个文档分别为1个order文档+2个order_item文档。声明了nested类型,每一个对象都会单独存储成一个新的文档,查询的时候能够独立进行查询,性能比inner object差,因为把order_item存储成了单独的文档,查询的中带order_item的条件的时候,就需要先查下order_item文档再根据order和order_item的关系进行查询order。nested object更新的代价较大,因为每个子文档的更新都需要重新建整个结构体的索引,所以nested object 不适合经常update的嵌套多级关系的场景。
本文来自网易实践者社区,经作者陈道秋授权发布。