【问题标题】:How to query nested doc of nested doc where email matches example@gmail.com如何查询电子邮件与 example@gmail.com 匹配的嵌套文档的嵌套文档
【发布时间】:2018-08-06 23:44:12
【问题描述】:

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

我正在尝试查找与另一个特定用户相关的用户付款。

我有一个获取用户付款的查询,其中填充了每个债务人的所有债务人和用户信息。

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 结构可以做到这一点吗?

【问题讨论】:

  • 类似.populate({path: 'payments', populate: {path: 'debtors', populate: {path: 'user’,match: { email: "john.smith@gmail.com" }}}})
  • @Veeram 它实际上并没有起作用。它仍在返回其他债务人,但会截断用户数据。我需要从债务人数组中截断谁债务人对象

标签: node.js mongodb mongoose aggregation-framework


【解决方案1】:

猫鼬填充中没有此类支持。您可以在 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() {...})

【讨论】:

  • 谢谢@Veeram。比我希望的要复杂一点,但也许我的数据库的结构不如它应该的那样。
  • 是的。 mongodb 通常最多可以在两个级别上运行。数据结构越深,查询、聚合和更新就越复杂。
猜你喜欢
  • 2018-03-09
  • 2021-05-01
  • 2017-03-22
  • 2013-08-28
  • 2021-11-12
  • 1970-01-01
  • 2020-11-28
  • 2021-02-25
  • 2016-08-16
相关资源
最近更新 更多