sql >> Database >  >> NoSQL >> MongoDB

Mongo - Match waar de objectsleutel variabel is

Gebruik met MongoDB 3.4.4 het aggregatieraamwerk om het document te doorzoeken. Dit wordt mogelijk gemaakt met de $objectToArray operator waarmee u de sleutels in het verwerkte veld kunt toewijzen aan een reeks sleutel/waarde-paren. De lijst zal gemakkelijk te filteren zijn en de sleutel(s) krijgen die overeenkomen met welke voorwaarde je ook hebt.

In het volgende voorbeeld bestaat de aggregatiepijplijn uit een extra veld dat de sleutel(s) bevat die voldoen aan de bovenstaande voorwaarde van een valse waarde, dus idealiter is het een array:

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

wat oplevert

{
    "_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"
    ]
}

Uitleg

Beginnend met de geneste uitdrukking

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

de invoer naar $filter operator { "$objectToArray": "$processed" } converteert de sleutels in de processed sleutel tot deze 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
    }
]

en $filter zal de bovenstaande array filteren om alleen de objectelementen te hebben waarvan v eigenschap is NOT true :

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

$map zal dan een toegewezen array retourneren met alleen de waarden

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

dus je eindigt met slechts

[ "original" ]

als resultaat.

Met oudere MongoDB-versies wordt het behoorlijk moeilijk om query's uit te voeren op dynamische sleutels. Overweeg om uw schema aan te passen om dit documentmodel te volgen dat gemakkelijker te doorzoeken is:

// 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 }
    ]
}

Uw zoekopdracht is eenvoudig

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

of gebruik $map en $filter om de sleutels terug te geven met false waarden als

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


  1. Hoe gebruik je pollingThrottle en pollingInterval?

  2. Voeg een string toe aan het einde van een bestaand veld in MongoDB

  3. Aanhoudend Python-object in het geheugen voor nginx/uwsgi-server

  4. Hoe kan ik subdocumenten uit een array halen?