对于1到N的关系,Mongo中的双向引用是否更有效?

时间:2017-09-25 13:24:18

标签: mongodb

我在工作中讨论了1到N关系中的双向引用。 According to this post in MongoDB blog,你可以做到。我们根本不需要原子更新,所以没问题。按照本文中的示例,在我们的示例中,您只能创建或删除任务,但不能更改任务所有者。

我的论点是双向引用可能更有效地从双方获取数据,因为我们需要在程序的不同部分更频繁地显示所有者的任务,而不仅仅是任务。我的同事说没有效率提升,数据重复是不值得的。

您对这种方法的效率有任何信息吗?

1 个答案:

答案 0 :(得分:0)

当我们减少写入次数和读取次数时,对数据进行反规范化和存储会有所帮助。这里的效率取决于数据的检索方式。如果我们从集合中检索数据需要双向引用,如果我们已经拥有它,那么肯定会提高查​​询效率。

学生收藏

 { _id:1, name: "Joseph", courses:[1, 3, 4]}
 { _id:2, name: "Mary", courses:[1, 3]}
 { _id:3, name: "Catherine", courses:[1, 2, 4]}
 { _id:4, name: "Robert", courses:[2, 4]}

课程集

 { _id:1, name: "Math101", students: [1, 2, 3]}
 { _id:2, name: "Science101", students: [3, 4]}
 { _id:3, name: "History101", students: [1, 2]}
 { _id:4, name: "Astronomy101", students: [1, 3, 4]}

考虑上面的学生和课程示例,这里完成了两种方式的参考,学生系列中的课程数组为我们提供了学生学习的不同课程。同样,Courses系列中的Students数组为我们提供了正在学习相应课程的学生。

如果我们要列出正在学习Math101的学生,那么查询将是

db.courses.aggregate([{$match: {name:"Math101"}},
  {$unwind:"$students"},
  {$lookup:{from:"students", 
            localField:"students", 
            foreignField:"_id", 
            as:"result"}}])
汇总管道中的

$match$unwind$lookup用于实现结果。 $ match减少数据(最好在聚合管道的开头使用此运算符),$ unwind来展开Courses集合中的students数组,$ lookup查看Students集合并获取学生详细信息< / p>

在我们的样本集合上执行上述聚合查询后的结果是

{
        "_id" : 1,
        "name" : "Math101",
        "students" : 1,
        "result" : [
                {
                        "_id" : 1,
                        "name" : "Joseph",
                        "courses" : [
                                1,
                                3,
                                4
                        ]
                }
        ]
}
{
        "_id" : 1,
        "name" : "Math101",
        "students" : 2,
        "result" : [
                {
                        "_id" : 2,
                        "name" : "Mary",
                        "courses" : [
                                1,
                                3
                        ]
                }
        ]
}
{
        "_id" : 1,
        "name" : "Math101",
        "students" : 3,
        "result" : [
                {
                        "_id" : 3,
                        "name" : "Catherine",
                        "courses" : [
                                1,
                                2,
                                4
                        ]
                }
        ]
}

双向引用的效率完全基于我们检索的内容,因此设计的架构与预期结果紧密相符。