Utilisation de MongoDB 3.4.4 et des versions plus récentes :
db.coll.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
Le pipeline ci-dessus donnera le résultat final
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
Explications
Le pipeline peut être décomposé pour afficher les résultats de chaque opérateur individuel.
$objectToArray
vous permet de transformer le document racine avec des clés dynamiques (indiquées par la variable système $$ROOT
) dans un tableau contenant un élément pour chaque paire champ/valeur du document d'origine. Chaque élément du tableau de retour est un document qui contient deux champs k et v. Exécuter le pipeline avec juste l'opérateur dans un $project
étape
db.coll.aggregate([
{ "$project": {
"keys": { "$objectToArray": "$$ROOT" }
} }
])
rendements
{
"_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"
}
}
]
}
Le $filter
agit comme un mécanisme de filtrage pour le tableau produit par $objectToArray
, fonctionne en sélectionnant un sous-ensemble du tableau à renvoyer en fonction de la condition spécifiée qui devient votre requête.
Considérez le pipeline suivant qui renvoie un tableau de la paire clé/valeur qui correspond à la condition { "samekeyA": "value1" }
db.coll.aggregate([
{ "$project": {
"keys": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
} }
])
qui donne
{
"_id" : 1,
"keys" : [
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
}
Cela transformera le tableau filtré ci-dessus de
[
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
au document d'origine avec la clé dynamique
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
donc en cours d'exécution du pipeline
db.coll.aggregate([
{ "$project": {
"key": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
produira
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
Cela promouvra le document de clé dynamique filtré au niveau supérieur et remplacera tous les autres champs. L'opération remplace tous les champs existants dans le document d'entrée, y compris le _id
champ.
Cela transforme essentiellement le document ci-dessus
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
au résultat final souhaité
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}