Как заполнить субдокумент в мангусте после его создания?

Я добавляю комментарий в список item.comments. Мне нужно получить пользовательские данные comment.created_by, прежде чем я выведу их в ответ. Как мне это сделать?

Item.findById(req.param('itemid'), function(err, item){ var comment = item.comments.create({ body: req.body.body , created_by: logged_in_user }); item.comments.push(comment); item.save(function(err, item){ res.json({ status: 'success', message: "You have commented on this item", //how do i populate comment.created_by here??? comment: item.comments.id(comment._id) }); }); //end item.save }); //end item.find 

Мне нужно заполнить поле comment.created_by здесь, в моем файле res.json:

  comment: item.comments.id(comment._id) 

comment.created_by – это ссылка на пользователя в моей комментариях Monongoose. В настоящее время он дает мне только идентификатор пользователя, мне нужно, чтобы он заполнялся всеми пользовательскими данными, за исключением полей пароля и солей.

Вот схема, как люди спрашивали:

 var CommentSchema = new Schema({ body : { type: String, required: true } , created_by : { type: Schema.ObjectId, ref: 'User', index: true } , created_at : { type: Date } , updated_at : { type: Date } }); var ItemSchema = new Schema({ name : { type: String, required: true, trim: true } , created_by : { type: Schema.ObjectId, ref: 'User', index: true } , comments : [CommentSchema] }); 

Чтобы заполнить ссылочные субдокументы, вам необходимо явно определить коллекцию документов, к которой ссылается идентификатор (например, created_by: { type: Schema.Types.ObjectId, ref: 'User' } ).

Учитывая, что эта ссылка определена и ваша схема также хорошо определена, теперь вы можете просто вызвать populate как обычно (например, populate('comments.created_by') )

Доказательство кода концепции:

 // Schema var mongoose = require('mongoose'); var Schema = mongoose.Schema; var UserSchema = new Schema({ name: String }); var CommentSchema = new Schema({ text: String, created_by: { type: Schema.Types.ObjectId, ref: 'User' } }); var ItemSchema = new Schema({ comments: [CommentSchema] }); // Connect to DB and instantiate models var db = mongoose.connect('enter your database here'); var User = db.model('User', UserSchema); var Comment = db.model('Comment', CommentSchema); var Item = db.model('Item', ItemSchema); // Find and populate Item.find({}).populate('comments.created_by').exec(function(err, items) { console.log(items[0].comments[0].created_by.name); }); 

Наконец, обратите внимание, что populate работает только для запросов, поэтому вам нужно сначала передать свой элемент в запрос, а затем вызвать его:

 item.save(function(err, item) { Item.findOne(item).populate('comments.created_by').exec(function (err, item) { res.json({ status: 'success', message: "You have commented on this item", comment: item.comments.id(comment._id) }); }); }); 

Возможно, это изменилось с момента написания первоначального ответа, но похоже, что теперь вы можете использовать функцию Population для этого, не выполняя лишний findOne. См .: http://mongoosejs.com/docs/api.html#model_Model.populate . Вы бы хотели использовать это внутри обработчика сохранения, как и findOne.

@ user1417684 и @ chris-foster правы!

выдержка из рабочего кода (без обработки ошибок):

 var SubItemModel = mongoose.model('subitems', SubItemSchema); var ItemModel = mongoose.model('items', ItemSchema); var new_sub_item_model = new SubItemModel(new_sub_item_plain); new_sub_item_model.save(function (error, new_sub_item) { var new_item = new ItemModel(new_item); new_item.subitem = new_sub_item._id; new_item.save(function (error, new_item) { // so this is a valid way to populate via the Model // as documented in comments above (here @stack overflow): ItemModel.populate(new_item, { path: 'subitem', model: 'subitems' }, function(error, new_item) { callback(new_item.toObject()); }); // or populate directly on the result object new_item.populate('subitem', function(error, new_item) { callback(new_item.toObject()); }); }); }); 

Я столкнулся с той же проблемой, но после нескольких часов усилий я нашел решение. Это может быть без использования внешнего плагина 🙂

 applicantListToExport: function (query, callback) { this .find(query).select({'advtId': 0}) .populate({ path: 'influId', model: 'influencer', select: { '_id': 1,'user':1}, populate: { path: 'userid', model: 'User' } }) .populate('campaignId',{'campaignTitle':1}) .exec(callback); } 
  • личное сообщение socket.io
  • Как определить IP-адрес пользователя в узле
  • Заполнение вложенного массива в мангусте
  • В чем разница между io.sockets.emit и трансляцией?
  • Многорядная вставка с pg-promiseм
  • Node.js - найти домашнюю директорию в агностическом режиме платформы
  • Строка Node.js Mongoose.js для функции ObjectId
  • Отправка электронной почты в Node.js?
  • Как обернуть буфер как stream stream2 Readable?
  • Обработка ошибок с помощью streamов node.js
  • Изменить расположение узла node_modules
  • Давайте будем гением компьютера.