Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a sample of each MongoDB aggregate group

I have a MongoDB collection of documents having two properties: type & value.

[
  {type: "A", value: "1"},
  {type: "A", value: "2"},
  {type: "B", value: "1"},
  {type: "B", value: "2"},
  {type: "C", value: "1"},
  {type: "C", value: "2"}
]

How can I get one random document of each type using a single query without any JavaScript involved?

I tried to figure something out using the aggregation framework

db.collection.aggregate([
  {$group: {_id: "$type", item: {$push: "$$ROOT"}}},
  {$sample: {size: 1}}
]);

which does not apply the sampling on each group but simply selects one of the groups.

like image 707
Mouz Avatar asked Nov 08 '22 06:11

Mouz


1 Answers

Alternatively, you can iterate on all grouped elements and process the random in another way than $sample :

db.collection.aggregate([
    { $group: { _id: "$type", item: { $push: "$$ROOT" } } }
]).forEach(function(data) {
    var rand = data.item[Math.floor(Math.random() * data.item.length)];
    // insert in a new collection if needed
    // db.results.insert(rand);
    printjson(rand);
});

To pick a random element from an array : Getting a random value from a JavaScript array

This solution can be slow as it doesn't use aggregation if you have a large distinct value of type in your collection

like image 109
Bertrand Martel Avatar answered Nov 15 '22 06:11

Bertrand Martel