【问题标题】:what does populate in mongoose mean?populate in mongoose 是什么意思?
【发布时间】:2016-10-29 08:24:51
【问题描述】:

我遇到了以下我无法理解的代码行,尽管有很多教程提供了与 populate 示例相关的信息,但没有一个可以解释它的确切含义。这是一个示例

var mongoose = require('mongoose'), Schema = mongoose.Schema

var PersonSchema = new Schema({
  name    : String,
  age     : Number,
  stories : [{ type: Schema.ObjectId, ref: 'Story' }]
});

var StorySchema = new Schema({
  _creator : {
     type: Schema.ObjectId,
     ref: 'Person'
  },
  title    : String,
  fans     : [{ type: Schema.ObjectId, ref: 'Person' }]
});

var Story  = mongoose.model('Story', StorySchema);
var Person = mongoose.model('Person', PersonSchema);
Story.findOne({ title: /Nintendo/i }).populate('_creator') .exec(function (err, story) {
if (err) ..
  console.log('The creator is %s', story._creator.name);
  // prints "The creator is Aaron"
})

【问题讨论】:

标签: mongoose mongoose-populate


【解决方案1】:

populate() 猫鼬中的函数用于填充引用中的数据。在您的示例中,StorySchema 具有 _creator 字段,该字段将引用 _id 字段,该字段基本上是 mongodb 文档的 ObjectId

populate() 函数可以接受字符串或对象作为输入。

其中 string 是需要填充的字段名称。在你的情况下是_creator。在 mongoose 从 mongodb 中找到一个文档后,结果如下所示

_creator: {
  name: "SomeName",
  age: SomeNumber,
  stories: [Set Of ObjectIDs of documents in stories collection in mongodb]
},
title: "SomeTitle",
fans: [Set of ObjectIDs of documents in persons collection in mongodb]

populate 也可以接受对象作为输入。

你可以在这里找到mongoose的populate()函数的文档: http://mongoosejs.com/docs/2.7.x/docs/populate.htmlhttps://mongoosejs.com/docs/populate.html

【讨论】:

  • 似乎是一种自动连接(JOIN a la SQL)。对吗?
【解决方案2】:

我偶然遇到了这个问题,但我觉得我需要在这里提供帮助,即使它很老,因为我不相信它的解释方式:

Populate() 函数填充...

这对于以英语为母语的人来说可能很清楚,但对其他人来说可能不是。

总之

Populate 会自动将文档中的指定路径替换为其他集合中的文档。

加长版

让我们举个例子:

Story.findOne({ title: Nintendo })

将返回这样的故事:

{
  _creator : A0jfdSMmEJj9, //id of the creator (totally random, just for a clear example)
    title    : Nintendo,
    fans     : [r432i900fds09809n, fdsjifdsjfueu88] // again, totally random that I've typed here
  }
}

在某些情况下,这种要求就足够了,因为我们不关心作者或粉丝,所以有一些 ID 不会打扰我们。

但如果我需要_creator 的名字,我需要发出另一个请求才能在数据库中找到它。 除了在 mongoose 中,我们有一个名为 populate() 的聪明函数,我们可以将它链接到我们之前的请求,以便直接在我们的答案中获取该信息,而无需明确执行额外的请求。

Story.findOne({ title: Nintendo }).populate('_creator')

会回来

{
  _creator : {
       _id : A0jfdSMmEJj*9,
       name: Sai,
       age: 100,
       stories : [fdsfdsfdsew38u, 89hr3232, ...]
    },
    title    : Nintendo,
    fans     : [r432i900fds09809n, fdsjifdsjfueu88]
  }
}

但也许,信息太多了,我们不希望他写的故事以及他的年龄和名字就足够了。填充可以然后接受包含我们需要的字段的其他参数

Story.findOne({ title: Nintendo }).populate('_creator', 'name age')

结果 ==>

{
  _creator : {
       name: Sai,
       age: 100,
    },
    title    : Nintendo,
    fans     : [r432i900fds09809n, fdsjifdsjfueu88]
  }
}

【讨论】:

  • 如果用户出版了 n 本书,那么我该如何退回所有文档?
  • 有人能解释一下这个“-__v”在填充中是什么意思吗? .populate("roles", "-__v") 如果需要,我可以提供更多信息,但我觉得这很明显,但我不知道。
  • 等等..如果我们不必再发出请求,那么它与 MySQL 数据库有何不同?我认为我们无法在 noSQL 数据库中的一个请求中检索关系数据,这就是我们进行数据非规范化的原因????
  • 这太棒了。
  • @AliAkber - 在 MongoDB 中,__v 属性是版本键,它的值是一个数字,表示文档的版本号。在数据不一致和版本冲突的情况下,它有助于数据完整性。查看此答案以获取更多信息:stackoverflow.com/a/12495922
【解决方案3】:

填充是自动将文档中的指定路径替换为其他集合中的文档的过程。我们可以填充单个文档、多个文档、一个普通对象、多个普通对象或从查询返回的所有对象。让我们看一些例子。

让我解释一下,如果您正在撰写博客文章,并且想要添加一个选项,让内容读者可以知道撰写博客的人,以便您可以通过以下方式使用它:

Blog.findOne({title:a random blog})

另一方面,如果你想返回写博客的博主的 id 和信息,你可以这样做:

Blog.findOne({title:a random blog}).populate(blogger)

你可以在很多方面使用它,这只是一个例子。

【讨论】:

    【解决方案4】:

    .populate() 被用于只带来需要的信息。

    不带 .populate() 的示例

    User.findOne({ name: Bob })
    

    会回来

    {
      Bob : {
        _id : dasd348ew,
        email: bob@example.com,
        age: 25,
        job: teacher,
        nationality: American,
      }
    }
    

    .populate() 示例

    User.findOne({ name: Bob }).populate("Bob", "job email")
    

    会回来

    {
      Bob : {
        job: teacher,
        email: bob@example.com,
      }
    }
    

    【讨论】:

      【解决方案5】:

      正如您阅读this answer(我很感激),但它并不完整。因此我决定自己写答案(因为此时编辑队列已满)。

      但如果您需要跨多个级别填充。我们可以得到一个用户的朋友列表,但是如果我们想检索一个用户的朋友的朋友,我们可以这样添加:

      const userSchema = new Schema({
        name: String,
        friends: [{ type: ObjectId, ref: 'User' }]
      });
      
      User.
        findOne({ name: 'Val' }).
        populate({
          path: 'friends',
          // Get friends of friends - populate the 'friends' array for every friend
          populate: { path: 'friends' }
        });
      

      【讨论】:

        猜你喜欢
        • 2017-11-10
        • 2015-01-03
        • 2018-04-17
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多