Finding multiple documents with one query

I have a schema like so:

schema
{
    owner: <id to other document type>
    created: date
}

I have an array of owner's ids: [owner_id_1, owner_id_2, ... owner_id_x]

I want to get a list of documents, with these owners, but limited to just the latest of each. Doing the queries individually:

find_one({ owner: owner_id_1 }).sort({ created: -1 }).limit(1)

But I don't want to have to fire off x of these, I'd like a way to do it in one query if possible

Upvotes: 1

Views: 245

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50406

The .aggregate() method allows you do do this, along with matching the documents via the $in operator:

collection.aggregate([
    { "$match": { "owner": { "$in": [owner_id_1, owner_id_2, ... owner_id_x] } },
    { "$group": {
        "_id": "$owner",
        "created": { "$max": "$created" }
    }}
])

Gets the maximum ( $max ) "created" value for each "owner" you asked for with the $in, which takes an array of values to match the field in the condition.

If you wanted more data than just that one field, the use $sort before you $group:

collection.aggregate([
    { "$match": { "owner": { "$in": [owner_id_1, owner_id_2, ... owner_id_x] } },
    { "$sort": { "owner": 1, "created": -1 } },
    { "$group": {
        "_id": "$owner",
        "created": { "$first": "$created" },
        "docId": { "$first": "$_id" },
        "something": { "$first": "$something" }
    }}
])

And the $first takes the first value ( descending was done in sort ) from each grouping boundary.

Upvotes: 2

Related Questions