node.js - example - node js express mongodb rest api
¿Cómo llenar un subdocumento en mangosta después de crearlo? (4)
Estoy agregando un comentario a una lista item.comments. Necesito obtener los datos de usuario de comment.created_by antes de mostrarlos en la respuesta. ¿Cómo debería hacer esto?
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
Necesito llenar el campo comment.created_by aquí en mi salida res.json:
comment: item.comments.id(comment._id)
comment.created_by es una referencia de usuario en mi mongoose CommentSchema. Actualmente solo me proporciona una identificación de usuario, la necesito completada con todos los datos de usuario, a excepción de los campos de contraseña y sal.
Aquí está el esquema que las personas han pedido:
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]
});
@ user1417684 y @ chris-foster tienen razón!
extracto del código de trabajo (sin manejo de errores):
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 @):
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());
});
});
});
Enfrenté el mismo problema, pero después de horas de esfuerzo encontré la solución. Puede ser sin usar ningún complemento externo :)
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);
}
Esto podría haber cambiado desde que se escribió la respuesta original, pero parece que ahora puede usar la función de llenado de Modelos para hacer esto sin tener que ejecutar un findOne adicional. Ver: http://mongoosejs.com/docs/api.html#model_Model.populate . Querrá utilizar esto dentro del controlador de guardar al igual que findOne.
Para completar los subdocumentos a los que se hace referencia, debe definir explícitamente la colección de documentos a la que hace referencia el ID (como created_by: { type: Schema.Types.ObjectId, ref: ''User'' }
).
Dado que esta referencia está definida y su esquema también está bien definido, ahora puede simplemente completar populate
como de costumbre (por ejemplo, populate(''comments.created_by'')
)
Código de prueba de concepto:
// 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);
});
Por último, tenga en cuenta que populate
solo funciona para las consultas, por lo que primero debe pasar su elemento a una consulta y luego llamarlo:
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)
});
});
});