【问题标题】:Mongo 3.2 join with specific itemMongo 3.2 加入特定项目
【发布时间】:2016-02-17 01:00:27
【问题描述】:

想象一下 Mongo 3.2 中的两个集合,称为 student 和 class。什么查询会返回特定班级中的所有学生文档。

$lookup 的聚合似乎想要对集合中的所有文档进行操作。例如返回每个班级的所有学生而不是特定的学生。

如何请求生成的学生文档属于特定班级,id=23945647b27e7e652a9aeb65?

类:

{
    "_id" : ObjectId("23945647b27e7e652a9aeb65"),  // Given this
    "name" : "Algebra",
    "students" : [ "13945647b27e7e65869aeb65", "03945647b27e7e65029aeb65" ]
}

学生://返回这个

{
    "_id" : ObjectId("13945647b27e7e65869aeb65"), 
    "name" : "foo"
}
{
    "_id" : ObjectId("03945647b27e7e65029aeb65"), 
    "name" : "bar"
}

一些失败的尝试:

db.student.aggregate([{$match:{"$ref": "class", "_id": ObjectId("23945647b27e7e652a9aeb65")}},{$lookup:{from: "class",localField:"students",foreignField: "_id", as: "stuffFromRight"}}}])


db.student.aggregate([{$lookup:{from: {"$ref": "class", "_id": ObjectId("23945647b27e7e652a9aeb65")},localField:"students",foreignField: "_id", as: "stuffFromRight"}}])

这个获得了部分功劳,因为它确实进行了正确的查找。但是,...,它不会将结果限制为我想要的特定类。

db.student.aggregate([{$lookup:{from: "class",localField:"students",foreignField: "_id", as: "stuffFromRight"}}])

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    该示例存在一些问题。

    1. 类中的数组与学生对象本身的类型不一样。您将无法将字符串与 ObjectId 进行比较并期望得到所需的结果。
    2. $lookup 对两个字段执行 $eq。在示例中,这意味着查找正在尝试比较:

      ["13945647b27e7e65869aeb65","03945647b27e7e65029aeb65"] == ObjectId("13945647b27e7e65869aeb65")

    由于上述两点,此查询将失败,最终将搜索所有文档。

    为了从班级使用学生数组,您需要先修复数组以匹配类型,然后您必须先展开数组,然后再执行查找。这是一个例子:

    db.class.aggregate([ 
        {$match:{ "_id": ObjectId("23945647b27e7e652a9aeb65")}}, 
        {$unwind: "$students"},
        {$lookup: { from: "student", localField: "students", foreignField: "_id", as: "stuffFromRight"}} 
    ])
    

    有了上面的结果,你可以使用一个项目来减少它,如果你愿意,只显示学生记录,但也可能值得把班级和学生拉到一起,因为无论如何你都可能需要查询班级在输出中。

    【讨论】:

    • students 是一个十六进制字符串,它等效于“new ObjectId(hexStr)”,但在最后一个查找阶段会导致空结果。展开生成类对象的多个副本,但“stuffFromRight”字段为空。需要的是 String->ObjectId 转换。
    • @redboy 在聚合中没有将字符串转换为 ObjectId 的选项,反之亦然。最终,需要修复数据,以免丢失其类型。您可能需要将学生数组拉入您的应用程序,然后在学生 ID 数组中的每个元素上正确设置类型后查询学生。
    猜你喜欢
    • 2011-08-08
    • 2017-08-06
    • 2020-10-30
    • 2020-09-19
    • 2020-08-03
    • 1970-01-01
    • 2017-12-07
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多