猫鼬填充不起作用

Posted

技术标签:

【中文标题】猫鼬填充不起作用【英文标题】:Mongoose Populate not working 【发布时间】:2014-12-19 01:03:01 【问题描述】:

您好,我有这个 Schema(称为 schema.js):

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

var RoomSchema = new Schema(
  name:  type: String, required: true, index:  unique: true  ,
  people:  type: Number, required: true ,
  childrens: type: Number, required: true,
  total: type: Number, required: true
);

var Room = mongoose.model('Room', RoomSchema);

var AvSchema = new Schema(
  roomId:  type: Schema.Types.ObjectId, ref: 'Room',
  people:  type: Number, required: true ,
  childrens: type: Number, required: true,
  total: type: Number, required: true
);

var Av = mongoose.model('Av', AvSchema);

module.exports = 
  Room: Room,
  Av: Av
;

在我的路线文件中:

module.exports = function(app) 
  var model = require('../models/Schema');

  app.get('/api/rooms', function(req, res) 
    model.Room.find(function(err, rooms) 
      if (err)
        res.send(err);

      res.json(rooms);
    );
  );


  app.get('/api/av', function(req, res) 
    model.Av.find().populate('roomId').exec(function(err, av) 
      if (err)
        res.send(err);

      res.json(av);
    );
  );
;

数据库的图片:

GET /api/rooms - 响应:

[
  "_id": "5444d0dd9a31437167eea816",
  "name": "Single",
  "people": 1,
  "childrens": 1,
  "total": 4
, 
  "_id": "5444d1009a31437167eea817",
  "name": "Double",
  "people": 2,
  "childrens": 2,
  "total": 10
]

当我调用 api/rooms 时看起来不错,但是当我调用 api/av 时,我得到一个空数组 [] ...。知道我做错了什么吗?我应该提一下,我已经在两个 roomsID 的 av 集合中插入了记录

提前谢谢你。

【问题讨论】:

【参考方案1】:

默认情况下,Mongoose 将模型名称复数以得出集合名称,因此 Mongoose 查找的是 avs 集合而不是 av

您可以通过将集合名称作为第三个参数传递给model 来显式设置集合名称:

var Av = mongoose.model('Av', AvSchema, 'av');

【讨论】:

SMH。不知道 Mongoose 有时是不是想为自己太聪明。我必须这样做: .populate('friendss');注意两个 ss。 @daCoda,我也遇到了同样的情况。如果您有一个“朋友”字段,则需要填充('friendss')【参考方案2】:

因为这是查询中最受欢迎的结果

猫鼬填充不起作用

我将包括它对我不起作用的原因,即使它不是对这个已经解决的问题的直接答案,希望它对某人有所帮助

我的问题是我在 select(.. 中指定了字段,但没有指定我试图填充的字段。

【讨论】:

【参考方案3】:

与 CodyBugstein 的回答类似,我发布了为什么它在我的情况下不起作用,即使它与 OP 的情况不同。

我试图在 .post('save') 钩子中填充架构的“pro”字段,如下所示:

mySchema.post('save', function(doc, next) 
    console.log(doc.pro); // Expected to log ObjectID
    doc.populate("pro"); // Populate field
    console.log(doc.pro); // Expected to log actual pro document

但是,第二个 console.log 也记录了 ObjectID 而不是文档。

在为此苦苦挣扎了一个小时并尝试了不同的方法之后,我发现我所要做的就是使用 Promise 并调用 execPopulate() 以便它返回一个成熟的 Promise。我使用了async/await,但你也可以使用.then

mySchema.post('save', async function(doc, next) 
    console.log(doc.pro); // Expected to log ObjectID
    await doc.populate("pro").execPopulate(); // Populate field
    console.log(doc.pro); // Expected to log actual pro document

这样,第二个console.log 确实按预期记录了整个专业文档:)

【讨论】:

【参考方案4】:

不要忘记将 ref 属性添加到您要填充的属性的架构中。例如

// ...
const orderSchema = new mongoose.Schema(
  userId: 
    type: Types.ObjectId,
    required: true
  ,
  reservationId: 
    type: Types.ObjectId,
    required: true,
    ref: 'Reservation' // <-- don't forget the ref
  
, 
  timestamps: true
)
// ...

见Mongoose Populate

【讨论】:

你先生,救了我的一天【参考方案5】:

对我来说,问题在于我不需要在文件开头填充模型。

【讨论】:

【参考方案6】:

我遇到了同样的问题,但没有一个对我有用。

我想在查询后填充文档。

这不起作用:

// IIFE for async/await
( async() => 

    var user = await User.findOne(  _id  );

    await user.populate( 'comments' ); // Doesn't work

 );

Mongoose Documentation explains 在没有回调的情况下调用 .populate() 时不会被执行。相反,您需要使用.populate().execPopulate():

// IIFE for async/await
( async() => 

    var user = await User.findOne(  _id  );

    await user.populate( 'comments' ).execPopulate(); // Works as expected

 );

【讨论】:

错误:execPopulate() 不是函数 这适用于 Mongoose 5。execPopulate() 在 Mongoose 6 中被删除:mongoosejs.com/docs/migrating_to_6.html#removed-execpopulate【参考方案7】:

还要检查您的架构在toJSONtoObject 选项中是否没有设置为true。 (自己捂脸)

See all schema options

【讨论】:

【参考方案8】:

对我来说,这是由于数据不正确。我要填充的 ID 已从主表中删除。 因此,当我进行填充时,它没有填充填充的数据,因为 Id 不在表中。

【讨论】:

我从上到下,这也是我的问题?‍♂️

以上是关于猫鼬填充不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Q 的猫鼬嵌套填充不起作用

虚拟填充猫鼬

猫鼬 findByIdAndUpdate 不起作用。 new: true 包括

猫鼬 TTL partialFilterExpression 不起作用?

猫鼬 TTL partialFilterExpression 不起作用?

猫鼬独特:真的不起作用[重复]