Utilizzo di MongoDB 3.4.4 e versioni successive:
db.coll.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
La pipeline di cui sopra produrrà l'output finale
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
Spiegazioni
La pipeline può essere scomposta per mostrare i risultati di ogni singolo operatore.
$objectToArray
consente di trasformare il documento radice con chiavi dinamiche (indicate dalla variabile di sistema $$ROOT
) in una matrice che contiene un elemento per ogni coppia campo/valore nel documento originale. Ogni elemento nell'array restituito è un documento che contiene due campi k e v. Esecuzione della pipeline solo con l'operatore in un $project
fase
db.coll.aggregate([
{ "$project": {
"keys": { "$objectToArray": "$$ROOT" }
} }
])
rendimenti
{
"_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"
}
}
]
}
Il $filter
operatore funge da meccanismo di filtraggio per l'array prodotto da $objectToArray
operatore, funziona selezionando un sottoinsieme dell'array da restituire in base alla condizione specificata che diventa la tua query.
Considera la seguente pipeline che restituisce un array della coppia chiave/valore che corrisponde alla condizione { "samekeyA": "value1" }
db.coll.aggregate([
{ "$project": {
"keys": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
} }
])
che produce
{
"_id" : 1,
"keys" : [
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
}
Questo trasformerà l'array filtrato sopra da
[
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
al documento originale con la chiave dinamica
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
quindi eseguendo la pipeline
db.coll.aggregate([
{ "$project": {
"key": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
produrrà
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
Ciò promuoverà il documento chiave dinamica filtrato al livello superiore e sostituirà tutti gli altri campi. L'operazione sostituisce tutti i campi esistenti nel documento di input, incluso il _id
campo.
In sostanza questo trasforma il documento sopra
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
all'output finale desiderato
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}