在猫鼬中填充的是什么意思?

时间:2016-06-27 10:46:29

标签: mongoose mongoose-populate

我遇到了以下我无法理解的代码行,尽管有很多教程提供了与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"
})

5 个答案:

答案 0 :(得分:9)

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

  

Populate()函数填充...

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

TL; DR

填充将自动用其他集合中的文档替换文档中的指定路径

长版

让我们举个例子

Story.findOne({ title: Nintendo })

将返回这样一个故事:

{
  _creator : A0jfdSMmEJj*9, //id of the creator (totaly random, just for a clear example)
    title    : Nintendo,
    fans     : [r432i900fds09809n, fdsjifdsjfueu88] // again, totaly random that i've typed here
  }
}

在某些情况下,这种请求就足够了,因为我们不关心作者或粉丝,所以拥有一些ID不会对我们造成太大困扰。

但是在我需要那个作者的情况下,我需要再次请求在数据库中找到它。 除了,在猫鼬中,我们有一个名为populate()的聪明函数,我们可以将其链接到先前的请求,以便直接在我们的答案中获取该信息,而无需明确地执行其他请求。

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

将返回

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

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

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

结果==>

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

答案 1 :(得分:2)

populate()函数是mongoose用于填充引用内的数据。在您的示例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也可以接受该对象作为输入。

您可以在下面找到populate()猫鼬功能的文件。 http://mongoosejs.com/docs/2.7.x/docs/populate.html

答案 2 :(得分:1)

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

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

  msg:
  - db_host1
  - db_host2

答案 3 :(得分:0)

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

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

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

,另一方面,如果您要返回ID和写博客的博客作者的信息,则可以这样做:

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

好吧,您可以通过多种方式使用它,但这只是其中的一个例子。

答案 4 :(得分:0)

.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,
  }
}