Michael Lewkowitz
Michael Lewkowitz

Reputation: 11

Return a subdocument based on one of it's properties using mongoose

Using mongoose, I want to search for subdocuments that have a certain property and return the most recent one.

// the relevant part of the user schema
id: String,
__history__: {
    reply: []
}

// the components of a 'reply' (not defined by a schema)
id: String,
createdAt: Date,
props {
    tipID: String
}

Given a specific user id, I want to search their reply[]s for replies that have a tipID in their props. I then want to return the tipID for the reply that has the most recent createdAt.

I'm new to - well - coding in general. Would love any pointers on how best to tackle this.

Upvotes: 1

Views: 547

Answers (3)

Michael Lewkowitz
Michael Lewkowitz

Reputation: 11

Because $elemMatch was returning an error (I think because reply wasn't a proper schema defined doc), I got the following to work instead.

User.findOne("_id": user._id}, function (err, doc) {
    var replies = doc.__history__.reply;
    for ( var i = 0; i < replies.length; i++ ) {
        if (replies[i].props.hasOwnProperty("tipId")) {
            // do something
            break; // stop because i only wanted the first hit
    }
}

Note: I didn't have to worry about sorting by time because __history__.reply items were already ordered by most recent first.

Upvotes: 0

Brant
Brant

Reputation: 1778

If you're only finding one document, then organize the replies something like this..

// find your doc by ID
user.findOne({ id: id }, function(err, doc) {
    // sort replies by createdAt date
    var replies = _.sortBy(doc.reply, function(reply) {
        return reply.createdAt.getTime(); // convert to seconds from jan 1, 1970
    });

    return replies[0].props.tipId;
})

Upvotes: 1

Ron Wertlen
Ron Wertlen

Reputation: 832

This is a duplicate question of Mongoose - finding subdocuments by criteria

For your specific question, the trick with mongoose subdocuments is twofold:

a) avoid nesting within subdocuments if you can, i.e. do not nest your attributes within propId rather put those attributes straight into the reply, whatever they may be.

b) use $elemMatch as suggested in the duplicate answer I quoted above. This will make sure that mongoDb finds the right documents, since mongoDb recognises {a:1,b:2} and {b:2,a:1} as two different subdocuments.

Upvotes: 1

Related Questions