sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongo - Match hvor objektnøglen er variabel

Med MongoDB 3.4.4 skal du bruge aggregeringsrammen til at forespørge dokumentet. Dette er gjort muligt med $objectToArray operator, som giver dig mulighed for at tilknytte nøglerne i det behandlede felt til en række nøgle/værdi-par. Listen vil være let at filtrere og få den eller de nøgler, der matcher den tilstand, du har.

I det følgende eksempel består aggregeringspipelinen af ​​et ekstra felt, som indeholder nøglen/nøglerne, der matcher ovenstående betingelse om at have en falsk værdi, så ideelt set vil det være et array:

db.collection.aggregate([
    { "$addFields": {
        "notProcessed": { 
            "$map" : {
                "input": {
                    "$filter": {
                        "input": { "$objectToArray": "$processed" },
                        "as": "el",
                        "cond": { "$not": "$$el.v" }
                    }
                },
                "in": "$$this.k"
            }
        }
    } }
])
 

hvilket giver

{
    "_id" : ObjectId("5501b1648ef0b4eccc41814e"),
    "link" : "xxxxx.jpg",
    "processed" : {
        "320" : true,
        "480" : true,
        "540" : true,
        "720" : true,
        "800" : true,
        "1080" : true,
        "original" : false,
        "iPhone" : true
    },
    "notProcessed" : [ 
        "original"
    ]
}
 

Forklaringer

Starter med det indlejrede udtryk

{
    "$filter": {
        "input": { "$objectToArray": "$processed" },
        "as": "el",
        "cond": { "$not": "$$el.v" }
    }
}
 

input til $filter operator { "$objectToArray": "$processed" } vil konvertere nøglerne i den processed nøglen til dette array:

[ { "k" : "320", "v" : true }, { "k" : "480", "v" : true }, { "k" : "540", "v" : true }, { "k" : "720", "v" : true }, { "k" : "800", "v" : true }, { "k" : "1080", "v" : true }, { "k" : "original", "v" : false }, { "k" : "iPhone", "v" : true } ]

og $filter vil filtrere ovenstående array til kun at have de objektelementer, hvis v egenskaben er NOT true :

[ 
    {
        "k" : "original",
        "v" : false
    }
]
 

$map vil derefter returnere et kortlagt array med kun værdierne

[ { "k" : "original", "v" : false } ] => [ "original" ]
 

så du ender med bare

[ "original" ]
 

som et resultat.

Med ældre MongoDB-versioner bliver det ret vanskeligt at udstede forespørgsler mod dynamiske nøgler. Overvej at ændre dit skema, så det følger denne dokumentmodel, som er nemmere at forespørge på:

// this operation changes the schema
var processed = [];
db.collection.find().forEach( function(doc) {
     for(key in doc.processed) {
        if(doc.processed.hasOwnProperty(key)) {
            var item = { key: key, value: doc.processed[key] }
            processed.push(item);            
        }
     }
     doc.processed = processed;
     db.collection.save(doc);
});

// modified schema    

{ 
    "link": "xxxxx.jpg"
    "_id": ObjectId("5501b1648ef0b4eccc41814e"),
    "processed": [
         { "key": "320", "value": true },
         { "key": "480", "value": true },
         { "key": "540", "value": true },
         { "key": "720", "value": true },
         { "key": "800", "value": true },
         { "key": "1080", "value": true },
         { "key": "original", "value": false },
         { "key": "iPhone", "value": true }
    ]
}
 

Din søgeforespørgsel vil være enkel

db.collection.find({"processed.value": false});
 

eller brug $map og $filter for at returnere nøglerne med false værdier som

db.collection.aggregate([
    { "$project": {
        "link": 1,
        "notProcessed": { 
            "$map" : {
                "input": {
                    "$filter": {
                        "input": "$processed",
                        "as": "el",
                        "cond": { "$not": "$$el.v" }
                    }
                },
                "in": "$$this.k"
            }
        }
    } }
])
 


  1. Sådan opretter du forbindelse til ElastiCache-klyngen ved hjælp af node.js

  2. Sådan indstilles featureCompatibilityVersion i MongoDB

  3. Hvordan udfører man en NOT IN-forespørgsel i mongodb uden at bruge $nin?

  4. Sådan udføres grundlæggende forespørgselsoperationer i MongoDB