Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose: Populate a populated field

I'm using MongoDB as a log keeper for my app to then sync mobile clients. I have this models set up in NodeJS:

var UserArticle = new Schema({
    date: { type: Number, default: Math.round((new Date()).getTime() / 1000) }, //Timestamp!
    user: [{type: Schema.ObjectId, ref: "User"}],
    article: [{type: Schema.ObjectId, ref: "Article"}],
    place: Number,    
    read: Number,     
    starred: Number,   
    source: String
});
mongoose.model("UserArticle",UserArticle);

var Log = new Schema({
    user: [{type: Schema.ObjectId, ref: "User"}],
    action: Number, // O => Insert, 1 => Update, 2 => Delete
    uarticle: [{type: Schema.ObjectId, ref: "UserArticle"}],
    timestamp: { type: Number, default: Math.round((new Date()).getTime() / 1000) }
});
mongoose.model("Log",Log);

When I want to retrive the log I use the follwing code:


var log = mongoose.model('Log');
log
.where("user", req.session.user)
.desc("timestamp")
.populate("uarticle")
.populate("uarticle.article")
.run(function (err, articles) {
if (err) {
    console.log(err);
        res.send(500);
    return;
}
res.json(articles);

As you can see, I want mongoose to populate the "uarticle" field from the Log collection and, then, I want to populate the "article" field of the UserArticle ("uarticle").

But, using this code, Mongoose only populates "uarticle" using the UserArticle Model, but not the article field inside of uarticle.

Is it possible to accomplish it using Mongoose and populate() or I should do something else?

Thank you,

like image 402
Francesc Avatar asked Dec 17 '11 09:12

Francesc


People also ask

Does Mongoose populate use lookup?

Mongoose's populate() method does not use MongoDB's $lookup behind the scenes. It simply makes another query to the database. Mongoose does not have functionalities that MongoDB does not have.

What is virtual populate in Mongoose?

Populate. Mongoose also supports populating virtuals. A populated virtual contains documents from another collection. To define a populated virtual, you need to specify: The ref option, which tells Mongoose which model to populate documents from.


1 Answers

From what I've checked in the documentation and from what I hear from you, this cannot be achieved, but you can populate the "uarticle.article" documents yourself in the callback function.

However I want to point out another aspect which I consider more important. You have documents in collection A which reference collection B, and in collection B's documents you have another reference to documents in collection C.

You are either doing this wrong (I'm referring to the database structure), or you should be using a relational database such as MySQL here. MongoDB's power relies in the fact you can embed more information in documents, thus having to make lesser queries (having your data in a single collection). While referencing something is ok, having a reference and then another reference doesn't seem like you're taking the full advantage of MongoDB here.

Perhaps you would like to share your situation and the database structure so we could help you out more.

like image 177
alessioalex Avatar answered Oct 16 '22 18:10

alessioalex