sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur man frågar efter en dynamisk nyckel - mongodb schemadesign

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

$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

$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"
            }
        }
    ]
}

$arrayToObject

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"
        }
    }
}

$replaceRoot

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"
    }
}


  1. MongoDB-struktur för meddelandeapp

  2. Mongoose går med i två samlingar och får refererade data i två egenskaper

  3. Hur släpper eller tar man bort en samling i MongoDB?

  4. Dra en post från en array via Meteor