Reputation: 132
I have a Meteor collection that has a field called type
. I'm wondering if there's a way to select one document of each type
. For example, if I had the following documents in my collection (sorted by descending createdAt
)
Document #1: {type = "apple", createdAt: ...}
Document #2: {type = "apple", createdAt: ...}
Document #3: {type = "grape", createdAt: ...}
Document #4: {type = "orange", createdAt: ...}
Document #5: {type = "orange", createdAt: ...}
Document #6: {type = "grape", createdAt: ...}
Document #7: {type = "apple", createdAt: ...}
...
Then how could I select 3 documents each with a unique type? In this example, I would need Document #1, #3, and #4.
Upvotes: 1
Views: 1983
Reputation: 6030
You could first find all the distinct types with
var distinctTypes = db.mycollection.distinct("type");
and then you can loop through to push all the documents from findOne
like so
var docs = [];
distinctTypes.forEach(function (thisType) {
docs.push(db.mycollection.findOne({type: thisType});
});
From here you can alter the above code to specify which one you want if there are multiples of each type.
UPDATE: Since Meteor still doesn't support distinct
, you can use the underscore uniq
like so
var distinctTypes = _.uniq(Collection.find({}, {
sort: {type: 1}, fields: {type: true}
}).fetch().map(function(x) {
return x.type;
}), true);
Upvotes: 3
Reputation: 307
You can do this in two steps: first, you get the counts using $group
, identified by type
, then $match
all that have count = 1.
db.fruit_collection.aggregate([
{ $match: {
createdAt: { $gt: ISODate("2015-08-01T12:00:00Z") }
}},
{ $group: {
_id: "$type",
count: { $sum: 1 }
}},
{ $match: {
count: 1
}}
]);
The first $match
is there as an example, so you can ignore. The second and the third part should give you the desired result.
Upvotes: 0