I'm trying to make an aggregate with mongodb. My goal is that I want to get random names starting with letters A to Z. As a result, each word starts with letter must be only once in the response but I can't figure out how to do it. I used match condition with regex and sample condition to get random documents.
Here is my collection;
[
{
"name": "ahmet"
},
{
"name": "barış"
},
{
"name": "ceyhun"
},
{
"name": "aslan"
},
{
"name": "deniz"
},
....
]
Here is my aggregate function;
db.collection.aggregate([
{
$match: {
name: {
$regex: "^a|^b|^c" // must be A to Z
}
}
},
{
"$sample": {
"size": 3 // Must be 26
}
}
])
I'm waiting response to be like this;
[
{
"name": "ahmet"
},
{
"name": "barış"
},
{
"name": "ceyhun"
},
.... // other words starting with d, e , f but only one word for each letter
]
But I'm getting;
[
{
"_id": ObjectId("5a934e000102030405000001"),
"name": "barış"
},
{
"_id": ObjectId("5a934e000102030405000003"),
"name": "aslan"
},
{
"_id": ObjectId("5a934e000102030405000000"),
"name": "ahmet"
},
// name => aslan, name => ahmet (Two words starting with same letter)
]
I'm newbie at mongodb and if anyone can help me where I'm wrong, I'll be appreciate.
CodePudding user response:
You can do something like this:
Edit:
db.collection.aggregate([
{
$group: {
_id: {$substr: ["$name", 0, 1]},
name: {$push: "$name"}
}
},
{
$project: {_id: 0,
name: {
$arrayElemAt: [
"$name",
{$toInt: {$multiply: [{$rand: {}}, {$size: "$name" }]}
}
]
}
}
}
])
As you can see on this playground example.
The $group
will keep a list of names per each firstL
, the $arryElemAt
with the $rand
will keep only a random item.