Todos. En la consulta del grupo mongo, el resultado muestra solo la (s) clave (s) en los argumentos. Cómo mantener el primer documento en cada grupo como grupo de consulta mysql. por ejemplo:
-------------------------------------------------------------------------
| 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 } })
resultado:
[
{
"name" : "ddl1st",
"count" : 1
},
{
"name" : "24k",
"count" : 1
}
]
Cómo conseguir lo siguiente:
[
{
"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'}
etc.? ¿Es posible simplemente tenerage: $age
?$group
_id, puede$sort
antes con el campo deseado y luego agrupar y usar operadores$first
u$last
en cualquier campo. Al acumular, la idea de incluir otros campos (que se acumulan / canalizan / reducen) no tiene tanto sentido ni siquiera teóricamente. Sin embargo, ordenar de antemano es en realidad ineficaz en comparación con ordenar cada grupo dentro de sí mismos, ya que los algoritmos de clasificación son más complejos que O (n). Ojalá hubiera mejores formas en MongoDB.Por cierto, si desea conservar no solo el primer documento, puede usar $ addToSet Por ejemplo:
db.test.aggregate({ $group: { _id: '$name', name : { $addToSet: '$name' } age : { $addToSet: '$age' }, count: { $sum: 1 } } }
fuente
[editado para incluir sugerencias de comentarios]
Vine aquí buscando una respuesta, pero no estaba contento con la respuesta seleccionada (especialmente dada su edad). Encontré esta respuesta que es una mejor solución (adaptada):
db.test.aggregate({ $group: { _id: '$name', person: { "$first": "$$ROOT" }, count: { $sum: 1 } }, { "$replaceRoot": { "newRoot": { "$mergeObjects": ["$person", { count: "$count" }]} } } }
fuente
count
campo. Necesitas usar$mergeObjects
para mantenerlo.{"$replaceRoot": {"newRoot": {"$mergeObjects": ["$person", {count: "$count"}]}}}
Puedes probar esto
db.test.aggregate({ { $group: { _id: '$name',count: { $sum: 1 }, data: { $push: '$$ROOT' } } }, { $project: { _id:0, data:1, count :1 } } }
fuente
Esto es lo que hice, funciona bien.
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 } }])
fuente
Solo una actualización rápida si uno enfrenta el mismo problema con documentos con numerosos campos. Se puede utilizar el poder de combinar la
$replaceRoot
etapa de la$mergeObjects
tubería y el operador de la tubería.db.users.aggregate([ { $group: { _id: '$name', user: { $first: '$$ROOT' }, count: { $sum: 1 } }, }, { $replaceRoot: { newRoot: { $mergeObjects: [{ count: '$count' }, '$user'] } } } ])
fuente
Úselo
$first
con el$$ROOT
documento y luego use$replaceRoot
con el primer campo.db.test.aggregate([ { "$group": { "_id": "$name", "doc": { "$first": "$$ROOT" } }}, { "$replaceRoot": { "newRoot": "$doc" }} ])
fuente
No sabía nada sobre
.group
helper, pero si prefiere utilizar Aggregation Framework , tendrá que especificar qué campos devolver. Corrígeme si me equivoco, pero en SQL tendrías que hacerlo de todos modos.Bueno, así es como lo haría con el Marco de agregación mencionado anteriormente:
db.test.aggregate({ $group: { _id: { name: "$name", city: "$city", fieldName: "$fieldName" }, count: { $sum: 1 } } })
fuente
Creé esta función para generalizar la inversión de una etapa de desenrollado ... avíseme si encuentran algún error con ella, ¡pero está funcionando bien para mí!
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 }
fuente
Si desea proyectar todos los campos, utilice la siguiente consulta.
db.persons.aggregate({ { $group: { _id: '$name', data: { $push: '$$ROOT' }, total: { $sum: 1 }} }, { $project: { _id:0, data:1, total :1 } } }
fuente
Aquí está la respuesta >>>>
$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();
fuente