【问题标题】:Populating all items from ref model [duplicate]填充参考模型中的所有项目[重复]
【发布时间】:2020-01-28 05:45:42
【问题描述】:

我的数据库结构如下:

我想从具有 x ID 的用户那里获取所有列表中的所有列表项。这样做的正确方法是什么?

我正在使用带有猫鼬的节点,我尝试了以下方法:

await User.findById(user._id).populate('list');

但意识到我无法从中填充所有ListItem。意思是,我不能这样做:

await User.findById(user._id).populate('list').populate('listItem');

如何从具有 x ID 的用户那里获取所有列表中的所有列表项?

【问题讨论】:

  • @NeilLunn 除了您提供的链接都与此无关....
  • @MattOestreich 重复项与“通过连接加入”完全匹配,这正是问题的实际要求。大多数关于加入主题的问题自然已经被提出并正确回答。

标签: node.js mongodb mongoose mongoose-populate


【解决方案1】:

假设UserListListItem 是集合,您应该能够使用$lookup.. 完成此操作。

Here is a live demo of the following query..


查询:

db.users.aggregate([
  {
    $match: {
      uniqueId: 1
    }
  },
  {
    $lookup: {
      from: "lists",
      localField: "uniqueId",
      foreignField: "userId",
      as: "lists"
    }
  },
  {
    $lookup: {
      from: "listItems",
      localField: "uniqueId",
      foreignField: "userId",
      as: "listItems"
    }
  }
])

数据集:

db={ // Simulates a DB  ********
  "users": [ // Simulates a Collection ********
    {
      "firstname": "John",
      "lastname": "Smith",
      "email": "jsmith@gmail.com",
      "password": "password123",
      "uniqueId": 1
    },
    {
      "firstname": "Jane",
      "lastname": "Doe",
      "email": "doe@yahoo.com",
      "password": "123password",
      "uniqueId": 2
    }
  ],
  "lists": [ // Simulates a Collection ********
    {
      "userId": 1,
      "name": "Johns List 1",
      "items": [
        11,
        12,
        13
      ]
    },
    {
      "userId": 2,
      "name": "Groceries",
      "items": [
        21,
        22,
        23
      ]
    }
  ],
  "listItems": [ // Simulates a Collection ********
    {
      "userId": 2,
      "itemId": 21,
      "title": "Apple",
      "notes": []
    },
    {
      "userId": 2,
      "itemId": 22,
      "title": "Banana",
      "notes": []
    },
    {
      "userId": 2,
      "itemId": 23,
      "title": "Strawberry",
      "notes": []
    },
    {
      "userId": 1,
      "itemId": 11,
      "title": "Oil Change",
      "notes": []
    },
    {
      "userId": 1,
      "itemId": 12,
      "title": "Pick Up Grandma",
      "notes": []
    },
    {
      "userId": 1,
      "itemId": 13,
      "title": "Go For Run",
      "notes": []
    }
  ]
}

结果:

[
  {
    "_id": ObjectId("5a934e000102030405000008"),
    "email": "jsmith@gmail.com",
    "firstname": "John",
    "lastname": "Smith",
    "listItems": [
      {
        "_id": ObjectId("5a934e000102030405000003"),
        "itemId": 11,
        "notes": [],
        "title": "Oil Change",
        "userId": 1
      },
      {
        "_id": ObjectId("5a934e000102030405000004"),
        "itemId": 12,
        "notes": [],
        "title": "Pick Up Grandma",
        "userId": 1
      },
      {
        "_id": ObjectId("5a934e000102030405000005"),
        "itemId": 13,
        "notes": [],
        "title": "Go For Run",
        "userId": 1
      }
    ],
    "lists": [
      {
        "_id": ObjectId("5a934e000102030405000006"),
        "items": [
          11,
          12,
          13
        ],
        "name": "Johns List 1",
        "userId": 1
      }
    ],
    "password": "password123",
    "uniqueId": 1
  }
]

【讨论】:

  • 谢谢!我会尽快尝试。附带问题,这是设计/创建数据库结构的好方法吗?
  • 我认为这取决于您对“好”的定义。如果我们谈论的是速度,我不确定在单独的集合中构建文档而不是嵌套文档时会影响性能。也就是说,如果您根据性能/速度定义“好”。对我来说,你的“模式”是有道理的并且看起来是可扩展的,所以我会说它很好。您可以使用内置的 ObjectID 来引用单独集合中的文档,但只要您保留唯一的引用就可以了。See this for more info
  • 有没有办法使用 populate 方法做到这一点?
  • 在 Mongoose 中使用 populate 方法在很大程度上依赖于您定义的 Mongoose 模式。如果正确定义了架构,则可以使用您在问题中提供的代码来完成。 You can read more here 在 Mongoose 架构/填充上。我明天可以测试一下,然后回复你。
  • 我明白了。非常感谢!
猜你喜欢
  • 2013-12-17
  • 2014-11-01
  • 2020-11-08
  • 2020-09-07
  • 1970-01-01
  • 2013-01-15
  • 2017-09-13
  • 2020-11-30
  • 1970-01-01
相关资源
最近更新 更多