2016-01-12 76 views
0

可以说我有3个类别:MongoDB的查询连接优化

Grandparents 
{ 
_id:1, 
name:old foo 
} 

Parents 
{ 
_id:2, 
grandparentId:1, 
name: foo 
} 
Person 
{ 
_id: 3, 
parentId:2, 
name: youngfoo 
} 

如何优化查询查找所有的人在那里人的祖父母的名字= X?

在这种情况下名称不是唯一的。

什么,我能想到的,到目前为止:
1.查询所有名称= X
2.查询所有的父母祖父母外祖父母那里IDS ==步骤得到1
3.查询所有的人在那里祖父母IDS父ids ==父母id从步骤2获得。

感觉不太高效。 mongodb能帮助我的专家吗?谢谢!

+0

你在关系模型的方式您的NoSQL数据库。尝试嵌入文档。如果你想有关系的方法只是尝试RDMS –

+0

我想过使用嵌入的方式,但事情是我也需要能够过滤父母和人...例如找到所有人的名字= y – user1955934

+0

@Undefined_variable这显然是错误的方法。 [嵌入任意数量的文件是万恶之源](http://blog.mahlberg.io/blog/2015/11/05/data-modelling-for-mongodb/)。一个[祖先数组](https://docs.mongodb.org/manual/tutorial/model-tree-structures-with-ancestors-array/)或物化路径是迄今为止最好的方法。 –

回答

0

我想你想要做这样的事情。我没有测试这个查询,但这是我会在你的地方尝试。这只在3.6 mongodb上才可能,因为它支持多个连接。这个想法是加入所有3个集合。首先加入的是父母和父母身份的人,以及人的“父母身份”。第二次加入是父母和祖父母。然后你用祖父母的名字过滤掉,你将得到一份包含祖父母,他的儿子(父母)和他的孙子(人)的文件。然后你只需要投影这个人。

db.Parents.aggregate([ 
     { 
      $lookup:{ 
      from:"Person", 
      localField:"_id", 
      foreignField:"parentId", 
      as:"Person" 
      } 
     }, 
     { 
      $unwind:"$Person" 
     }, 
     { 
      $lookup:{ 
      from:"Grandparents", 
      localField:"grandparentId", 
      foreignField:"_id", 
      as:"Grandparents" 
      } 
     }, 
     { 
      $unwind:"$Grandparents" 
     }, 
     {$match:{Grandparents.name:"x"}}, 
     {$project:{Person.name:1,Person._id:1}} 
}]) 

我认为这将这样的伎俩