Semua orang. Dalam kueri grup mongo, hasilnya hanya menampilkan kunci dalam argumen. Bagaimana cara menyimpan dokumen pertama di setiap grup seperti grup kueri mysql. sebagai contoh:
-------------------------------------------------------------------------
| name | age | sex | province | city | area | address |
-------------------------------------------------------------------------
| ddl1st | 22 | 纯爷们 | BeiJing | BeiJing | ChaoYang | QingNianLu |
| ddl1st | 24 | 纯爷们 | BeiJing | BeiJing | XuHui | ZhaoJiaBangLu |
| 24k | 220 | ... | .... | ... | ... | ... |
-------------------------------------------------------------------------
db.users.group({key: { name: 1},reduce: function ( curr, result ) { result.count ++ },initial: {count : 0 } })
hasil:
[
{
"name" : "ddl1st",
"count" : 1
},
{
"name" : "24k",
"count" : 1
}
]
Cara mendapatkan yang berikut ini:
[
{
"name" : "ddl1st",
"age" : 22,
"sex" : "纯爷们",
"province" : "BeiJing",
"city" : "BeiJing",
"area" : "ChaoYang",
"address" : "QingNianLu",
"count" : 1
},
{
"name" : "24k",
"age" : 220,
"sex" : "...",
"province" : "...",
"city" : "...",
"area" : "...",
"address" : "...",
"count" : 1
}
]
{$first: '$age'}
dll? Apakah mungkin untuk memilikinyaage: $age
?$group
_id, Anda dapat$sort
sebelumnya dengan bidang yang diinginkan kemudian mengelompokkan dan menggunakan$first
atau$last
operator di bidang apa pun. Saat terakumulasi, gagasan untuk memasukkan bidang lain (yang diakumulasikan / disalurkan / dikurangi) tidak masuk akal bahkan secara teoritis. Namun, pengurutan sebelumnya sebenarnya tidak efisien dibandingkan dengan pengurutan setiap grup di dalam dirinya sendiri karena algoritme pengurutan lebih kompleks daripada O (n). Saya berharap akan ada cara yang lebih baik di MongoDB.Ngomong-ngomong, jika Anda ingin menyimpan tidak hanya dokumen pertama, Anda dapat menggunakan $ addToSet Misalnya:
db.test.aggregate({ $group: { _id: '$name', name : { $addToSet: '$name' } age : { $addToSet: '$age' }, count: { $sum: 1 } } }
sumber
[diedit untuk menyertakan saran komentar]
Saya datang ke sini mencari jawaban tetapi tidak senang dengan jawaban yang dipilih (terutama mengingat usianya). Saya menemukan jawaban ini yang merupakan solusi yang lebih baik (diadaptasi):
db.test.aggregate({ $group: { _id: '$name', person: { "$first": "$$ROOT" }, count: { $sum: 1 } }, { "$replaceRoot": { "newRoot": { "$mergeObjects": ["$person", { count: "$count" }]} } } }
sumber
count
lapangan. Anda perlu menggunakan$mergeObjects
untuk menyimpannya.{"$replaceRoot": {"newRoot": {"$mergeObjects": ["$person", {count: "$count"}]}}}
Anda bisa mencobanya
db.test.aggregate({ { $group: { _id: '$name',count: { $sum: 1 }, data: { $push: '$$ROOT' } } }, { $project: { _id:0, data:1, count :1 } } }
sumber
Ini yang saya lakukan, itu berfungsi dengan baik.
db.person.aggregate([ { $group: { _id: '$name'}, // pass the set of field to be grouped age : { $first: '$age' }, // retain remaining field count: { $sum: 1 } // count based on your group }, { $project:{ name:"$_id.name", age: "$age", count: "$count", _id:0 } }])
sumber
Hanya pembaruan cepat jika seseorang menghadapi masalah yang sama dengan dokumen dengan berbagai bidang. Seseorang dapat menggunakan kekuatan menggabungkan
$replaceRoot
tahap pipa dan$mergeObjects
operator pipa.db.users.aggregate([ { $group: { _id: '$name', user: { $first: '$$ROOT' }, count: { $sum: 1 } }, }, { $replaceRoot: { newRoot: { $mergeObjects: [{ count: '$count' }, '$user'] } } } ])
sumber
Gunakan
$first
dengan$$ROOT
dokumen dan kemudian gunakan$replaceRoot
dengan bidang pertama.db.test.aggregate([ { "$group": { "_id": "$name", "doc": { "$first": "$$ROOT" } }}, { "$replaceRoot": { "newRoot": "$doc" }} ])
sumber
Saya tidak tahu tentang
.group
helper, tetapi jika Anda lebih suka menggunakan Aggregation Framework , Anda harus menentukan bidang mana yang akan dikembalikan. Koreksi saya jika saya salah, tetapi dalam SQL Anda harus tetap melakukannya.Nah, inilah cara Anda melakukannya dengan Kerangka Agregasi yang disebutkan sebelumnya:
db.test.aggregate({ $group: { _id: { name: "$name", city: "$city", fieldName: "$fieldName" }, count: { $sum: 1 } } })
sumber
Saya membuat fungsi ini untuk menggeneralisasi membalikkan tahap bersantai ... beri tahu saya jika kalian menemukan bug dengannya, tetapi berfungsi dengan baik untuk saya!
const createReverseUnwindStages = unwoundField => { const stages = [ // // Group by the unwound field, pushing each unwound value into an array, // // Store the data from the first unwound document // (which should all be the same apart from the unwound field) // on a field called data. // This is important, since otherwise we have to specify every field we want to keep individually. // { $group: { _id: '$_id', data: {$first: '$$ROOT'}, [unwoundField]: {$push: `$${unwoundField}`}, }, }, // // Copy the array of unwound fields resulting from the group into the data object, // overwriting the singular unwound value // { $addFields: {[`data.${unwoundField}`]: `$${unwoundField}`}, }, // // Replace the root with our data object // { $replaceRoot: { newRoot: '$data', }, }, ] return stages }
sumber
Jika Anda ingin memproyeksikan semua bidang dokumen, gunakan kueri di bawah ini.
db.persons.aggregate({ { $group: { _id: '$name', data: { $push: '$$ROOT' }, total: { $sum: 1 }} }, { $project: { _id:0, data:1, total :1 } } }
sumber
Inilah jawabannya >>>>
$m = new \MongoDB\Driver\Manager(); $command = new \MongoDB\Driver\Command([ 'aggregate' => 'mytestusers', 'pipeline' => [ ['$match' => ['name' => 'Pankaj Choudhary']], ['$unwind'=>'$skills'], ['$lookup' => array('from'=>'mytestskills','localField'=>'skills','foreignField'=>'_id','as'=>'sdfg')], ['$unwind'=>'$sdfg'], ['$group'=>array('_id'=>array('_id'=>'$_id','name'=>'$name','email'=>'$email'),'skills'=>array('$push'=>'$skills'),'sdfg'=>array('$push'=>'$sdfg'))], ], 'cursor' => new \stdClass, ]); $cursor = $m->executeCommand('targetjob-plus', $command); $result = $cursor->toArray();
sumber