本人近期在做ES替代关系型数据库其中遇到不少问题。在关系型数据库中有大量存在关系的表,在es中实现的话有三种方法:1、应用层join,通过多次查询实现,听起来就很复杂也不优雅。2、嵌套查询,也就是一个doc上存储多个nested 类型的数据,通俗的说就是数据库多张表的字段挤在一个es doc上。数据冗余。3、父子关系,最接近我们的需求(当文档索引性能远比查询性能重要 的时候,父子关系是非常有用的,但是它也是有巨大代价的。其查询速度会比同等的嵌套查询慢5到10倍!)。但是在es5.53中发现祖辈与孙辈查询有问题!
PUT /family
{
"mappings": {
"a":{
},
"b":{
"_parent": {
"type": "a"
}
},
"c":{
"_parent": {
"type": "b"
}
}
}
}
PUT /family/a/
{
"index": {
"_id": "1"
}
}
{
"id": 1,
"name": "亚朵酒店"
}
PUT /family/b/11?parent=1
{
"id": 11,
"name": "周边同类型"
}
PUT /family/c/111?parent=11
{
"id": 111,
"name": "周边酒店价格",
"price":"128"
}
GET /family/a/_search
{
"query": {
"has_child": {
"type": "b",
"query": {
"has_child": {
"type": "c",
"query": {
"match": {
"name": "价格"
}
}
}
}
}
}
}
如上代码所示,a是b的父,b是c的父. a<-b<-c 这样的关系.查询时,a与b的关系查询完全没有问题,b与c的查询永远没有返回结果,不知道是什么情况!
同时欢迎,大家推荐es join的最佳实践
1 个回复
ozing21sdo - 90后IT小白
赞同来自: kennywu76
c文档的路由依赖其父文档 ID — 也就是 b— 但是 b 文档的路由却依赖 其本身的 父文档 ID — 也就是 a 。此种情况下,孙辈文档很有可能最终和父辈、祖辈文档不在同一分片上,导致不满足祖辈和孙辈文档必须在同一个分片上被索引的要求。
解决方案是添加一个额外的 routing 参数,将其设置为祖辈的文档 ID ,以此来保证三代文档路由到同一个分片上。索引请求如下所示: