如何查询嵌套doc的嵌套doc,其中email与example@gmail.com匹配

时间:2018-02-27 10:46:36

标签: node.js mongodb mongoose aggregation-framework

用户有很多付款,付款有很多债务人,债务人属于用户。

我正在尝试查找与其他特定用户相关的用户付款。

我有一个查询,可以获得用户付款,其中包含每个债务人的所有债务人和用户信息。

const user_1 = await this.userModel
        .findOne({email: "geoffery.brown@gmail.com"})
        .populate({path: 'payments', populate: {path: 'debtors', populate: {path: 'user'}}})

返回如下内容:

{
    "payments": [
        {
            "debtors": [
                {
                    "_id": "5a9531b0de918e42c94947cc",
                    "amount": 15,
                    "user": {
                        "payments": [],
                        "created_at": "2018-02-27T10:14:39.847Z",
                        "_id": "5a95300388740142774f49c9",
                        "first_name": "John",
                        "last_name": "Smith",
                        "email": "john.smith@gmail.com",
                        "__v": 0
                    },
                    "__v": 0
                },
                {
                    "_id": "5a9531b0de918e42c94947cd",
                    "amount": 10,
                    "user": {
                        "payments": [],
                        "created_at": "2018-02-27T10:14:39.847Z",
                        "_id": "5a95302188740142774f49ca",
                        "first_name": "Joe",
                        "last_name": "Blogs",
                        "email": "joe.blogs@hotmail.com",
                        "__v": 0
                    },
                    "__v": 0
                }
            ],
            "created_at": "2018-02-27T10:23:31.561Z",
            "_id": "5a9531b0de918e42c94947ce",
            "date": "2018-02-26T10:54:36.167Z",
            "reference": "Food",
            "__v": 0
        }
    ],
    "created_at": "2018-02-27T10:14:39.847Z",
    "_id": "5a952fc488740142774f49c8",
    "first_name": "Geoffery",
    "last_name": "Brown",
    "email": "geoffery.brown@gmail.com",
    "__v": 0
}

我希望我的mongo查询能够过滤email === "john.smith@gmail.com"

的债务人

这可能与我目前的mongodb结构有关吗?

1 个答案:

答案 0 :(得分:1)

mongoose populate中没有这样的支持。您可以在3.4中使用如下所示的汇总。

类似于填充的概念,但所有繁重的工作都是在聚合框架内的单个服务器调用中完成的。

$lookup阶段用于从不同的引用集合中提取数据。

$unwind阶段展平结构以便后续查找。

$group分阶段将债务人纳入主要文件中的付款和付款阵列。

this.userModel.aggregate([
    {"$match":{"email": "geoffery.brown@gmail.com"}}, 
    {"$lookup":{
      "from":"payments", // name of the collection
      "localField":"payments",
      "foreignField":"_id",
      "as":"payments"
    }},
    {"$unwind":"$payments"},
    {"$lookup":{
      "from":"debtors", // name of the collection
      "localField":"payments.debtors",
      "foreignField":"_id",
      "as":"debtors"
    }},
    {"$project":{"payments.debtors":0}},
    {"$unwind":"$debtors"},
    {"$lookup":{
      "from":"users", // name of the collection
      "localField":"debtors.user",
      "foreignField":"_id",
      "as":"debtors.user"
    }},
    {"$unwind":"$debtors.user"},
    {"$match":{"debtors.user.email":"john.smith@gmail.com"}},
    {"$group":{
      "_id":{id:"$_id",payment_id:"$payments._id"},
      "created_at":{"$first":"$created_at"},
      "first_name":{"$first":"$first_name"},
      "last_name": {"$first":"$last_name"},
      "email": {"$first":"$email"},
      "payments":{"$first":"$payments"},
      "debtors":{"$push":"$debtors"}
    }},
    {"$addFields":{"payments.debtors":"$debtors"}},
    {"$project":{"debtors":0}},
    {"$group":{
      "_id":"$_id.id",
      "created_at":{"$first":"$created_at"},
      "first_name":{"$first":"$first_name"},
      "last_name": {"$first":"$last_name"},
      "email": {"$first":"$email"},
      "payments":{"$push":"$payments"}
    }}
    ]).exec(function() {...})