Con MongoDB 3.4.4 y versiones más recientes:
db.coll.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
La canalización anterior producirá el resultado final
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
Explicaciones
La canalización se puede descomponer para mostrar los resultados de cada operador individual.
$objectToArray
le permite transformar el documento raíz con claves dinámicas (indicado por la variable del sistema $$ROOT
) en una matriz que contiene un elemento para cada par de campo/valor en el documento original. Cada elemento de la matriz de retorno es un documento que contiene dos campos k y v. Ejecutar la canalización solo con el operador en un $project
escenario
db.coll.aggregate([
{ "$project": {
"keys": { "$objectToArray": "$$ROOT" }
} }
])
rendimientos
{
"_id" : 1,
"keys" : [
{
"k" : "_id",
"v" : 1
},
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
},
{
"k" : "key2",
"v" : {
"samekeyA" : "value3",
"samekeyB" : "value4"
}
},
{
"k" : "key3",
"v" : {
"samekeyA" : "value5",
"samekeyB" : "value6"
}
}
]
}
El $filter
El operador actúa como un mecanismo de filtrado para la matriz producida por $objectToArray
operador, funciona seleccionando un subconjunto de la matriz para devolver en función de la condición especificada que se convierte en su consulta.
Considere la siguiente canalización que devuelve una matriz del par clave/valor que coincide con la condición { "samekeyA": "value1" }
db.coll.aggregate([
{ "$project": {
"keys": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
} }
])
que produce
{
"_id" : 1,
"keys" : [
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
}
Esto transformará la matriz filtrada arriba de
[
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
al documento original con la clave dinámica
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
entonces ejecutando la canalización
db.coll.aggregate([
{ "$project": {
"key": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
producirá
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
Esto promoverá el documento clave dinámico filtrado al nivel superior y reemplazará todos los demás campos. La operación reemplaza todos los campos existentes en el documento de entrada, incluido el _id
campo.
Esencialmente, esto transforma el documento anterior
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
al resultado final deseado
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}