one multiple many fields array mongodb mongoose populate

mongodb - many - multiple populate mongoose



Mangosta: poblaciĆ³n profunda(poblar un campo poblado) (7)

En primer lugar, actualice la mangosta 3 a 4 y luego use la forma más sencilla para la población profunda en mangosta, tal como se muestra a continuación:

Supongamos que tiene el esquema de Blog que tiene ID de usuario como ID de referencia y luego en Usuario tiene alguna revisión como ID de referencia para revisión de esquema. Entonces, básicamente, tienes tres esquemas: 1. Blog 2. Usuario 3. Revisión

Y, debe consultar desde el blog, qué usuario posee este blog y la opinión del usuario. Para que pueda consultar su resultado como:

<BlogModel>.find({}).populate({path : ''userId'', populate : {path : ''reviewId''}}).exec(function (err, res) { })

Tengo el modelo de Category :

Category: ... articles: [{type:ObjectId, ref:''Article''}]

El modelo de artículo contiene ref. Account model .

Article: ... account: {type:ObjectId, ref:''Account''}

Entonces, con el modelo de categoría de articles poblados, será:

{ //category articles: //this field is populated [ { account: 52386c14fbb3e9ef28000001, // I want this field to be populated date: Fri Sep 20 2013 00:00:00 GMT+0400 (MSK), title: ''Article 1'' } ], title: ''Category 1'' }

La pregunta es: ¿cómo llenar el subcampo (cuenta) de un campo poblado ([artículos])? Así es como lo hago ahora:

globals.models.Category .find issue : req.params.id null sort: order: 1 .populate("articles") # this populates only article field, article.account is not populated .exec (err, categories) -> console.log categories

Sé que fue discutido aquí: Mangosta: poblar un campo poblado pero no se encontró una solución real


La forma más sencilla de lograr esto en 3.6 es utilizar Model.populate .

User.findById(user.id).select(''-salt -hashedPassword'').populate(''favorites.things'').exec(function(err, user){ if ( err ) return res.json(400, err); Thing.populate(user.favorites.things, { path: ''creator'' , select: ''-salt -hashedPassword'' }, function(err, things){ if ( err ) return res.json(400, err); user.favorites.things = things; res.send(user.favorites); }); });


Lamento estallar tu burbuja, pero no hay una solución directamente compatible con esto. En cuanto al número 601 de Github , parece sombrío. De acuerdo con las notas de la versión 3.6 , parece que los desarrolladores reconocieron que el problema es feliz con la población manual recursiva / profunda.

Por lo tanto, a partir de las notas de la versión, el método recomendado es anidar las llamadas pobladas en la devolución de llamada, por lo que en su función exec() , use categories.populate para completar más antes de enviar una respuesta.



Poblando a través de múltiples niveles

Supongamos que tiene un esquema de usuario que realiza un seguimiento de los amigos del usuario.

var userSchema = new Schema({ name: String, friends: [{ type: ObjectId, ref: ''User'' }] });

Populate te permite obtener una lista de los amigos de un usuario, pero ¿y si también quisieras los amigos de un amigo? Especifique la opción populate para indicar a mongoose que complete el conjunto de amigos de todos los amigos del usuario:

User.findOne({ name: ''Val'' }).populate({ path: ''friends'', // Get friends of friends - populate the ''friends'' array for every friend populate: { path: ''friends'' } });

Referencia: http://mongoosejs.com/docs/populate.html#deep-populate


Puede ser un poco tarde, pero escribí un plugin Mongoose para realizar una población profunda en cualquier nivel anidado arbitrario. Con este complemento registrado, puede completar los artículos y las cuentas de la categoría con solo una línea:

Category.deepPopulate(categories, ''articles.account'', cb)

También puede especificar opciones de relleno para controlar cosas como limit , select ... para cada ruta poblada. Consulte la documentación del complemento para obtener más información.


globals.models.Category.find() .where(''issue'', req.params.id) .sort(''order'') .populate(''articles'') .exec(function(err, categories) { globals.models.Account.populate(categories, ''articles.account'', function(err, deepResults){ // deepResult is populated with all three relations console.log(deepResults[0].articles[0].account); }); });

El siguiente ejemplo está inspirado en la pregunta formulada @codephobia y llena dos niveles de muchas relaciones. Primero busque un user , orderDetail su matriz de order relacionadas e incluya cada orderDetail .

user.model.findOne() .where(''email'', ''***@****.com'') .populate(''orders'') .exec(function(err, user) { orderDetail.model.populate(user, ''orders.orderDetails'', function(err, results){ // results -> user.orders[].orderDetails[] }); });

Esto funciona bien en 3.8.8 pero debería funcionar en 3.6.x