Använda MongoDB 3.4.4 och nyare versioner:
db.coll.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
Ovanstående pipeline kommer att ge slutresultatet
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
Förklaringar
Pipelinen kan delas upp för att visa varje enskild operatörs resultat.
$objectToArray
gör att du kan transformera rotdokumentet med dynamiska nycklar (betecknas med systemvariabeln $$ROOT
) till en array som innehåller ett element för varje fält/värdepar i originaldokumentet. Varje element i returmatrisen är ett dokument som innehåller två fält k och v. Kör pipelinen med bara operatören i en $project
skede
db.coll.aggregate([
{ "$project": {
"keys": { "$objectToArray": "$$ROOT" }
} }
])
ger
{
"_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"
}
}
]
}
$filter
operatorn fungerar som en filtreringsmekanism för arrayen som produceras av $objectToArray
operator, fungerar genom att välja en delmängd av arrayen att returnera baserat på det angivna villkoret som blir din fråga.
Tänk på följande pipeline som returnerar en array av nyckel/värdeparet som matchar villkoret { "samekeyA": "value1" }
db.coll.aggregate([
{ "$project": {
"keys": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
} }
])
vilket ger
{
"_id" : 1,
"keys" : [
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
}
Detta kommer att omvandla den filtrerade arrayen ovan från
[
{
"k" : "key1",
"v" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
]
till originaldokumentet med den dynamiska nyckeln
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
så kör pipelinen
db.coll.aggregate([
{ "$project": {
"key": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "el",
"cond": {
"$eq": [
"$$el.v.samekeyA",
"value1"
]
}
}
}
}
} }
])
kommer att producera
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
Detta kommer att flytta upp det filtrerade dynamiska nyckeldokumentet till toppnivån och ersätter alla andra fält. Operationen ersätter alla befintliga fält i inmatningsdokumentet, inklusive _id
fält.
Detta förvandlar i huvudsak ovanstående dokument
{
"_id" : 1,
"key" : {
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}
}
till önskad sluteffekt
{
"key1" : {
"samekeyA" : "value1",
"samekeyB" : "value2"
}
}