sql >> Database >  >> NoSQL >> MongoDB

MongoDB document invoegen of veld verhogen indien aanwezig in array

Met MongoDB 4.2 en nieuwer kan de updatemethode nu een document of een geaggregeerde pijplijn waarbij de volgende fasen kunnen worden gebruikt:

  1. $addFields en zijn alias $set
  2. $project en zijn alias $unset
  3. $replaceRoot en zijn alias $replaceWith .

Gewapend met het bovenstaande, zal uw update-bewerking met de geaggregeerde pijplijn zijn om de tags te overschrijven veld door een gefilterde tags aan elkaar te koppelen array en een toegewezen array van de invoerlijst met wat gegevenszoekacties in de kaart:

Om te beginnen gebruikt de geaggregeerde expressie die de tags-array filtert de $filter en het volgt:

const myTags = ["architecture", "blabladontexist"];

{ 
    "$filter": { 
        "input": "$tags",
        "cond": { 
            "$not": [
                { "$in": ["$$this.t", myTags] } 
            ] 
        }
    } 
}

die de gefilterde reeks documenten produceert

[  
    { "t" : "contemporary", "n" : 2 }, 
    { "t" : "creative", "n" : 1 }, 
    { "t" : "concrete", "n" : 3 }
]

Nu zal het tweede deel zijn om de andere array af te leiden die aan het bovenstaande wordt gekoppeld. Deze array vereist een $map over de myTags invoerarray als

{ 
    "$map": { 
        "input": myTags,
        "in": {
            "$cond": {
                "if": { "$in": ["$$this", "$tags.t"] },
                "then": { 
                    "t": "$$this", 
                    "n": { 
                        "$sum": [
                            { 
                                "$arrayElemAt": [
                                    "$tags.n", 
                                    { "$indexOfArray": [ "$tags.t", "$$this" ] } 
                                ] 
                            },
                            1
                        ]
                    } 
                },
                "else": { "t": "$$this", "n": 0 }
            }
        }
    } 
}

De bovenstaande $map loopt in wezen over de invoerarray en controleert bij elk element of het in de tags staat array die de t . vergelijkt eigenschap, als deze bestaat, dan is de waarde van de n veld van het subdocument wordt zijn huidige n waarde uitgedrukt met

{ 
    "$arrayElemAt": [
        "$tags.n", 
        { "$indexOfArray": [ "$tags.t", "$$this" ] } 
    ] 
}

voeg anders het standaarddocument toe met een n-waarde van 0.

Over het algemeen zal uw update-bewerking als volgt zijn

Uw laatste update-bewerking wordt:

const myTags = ["architecture", "blabladontexist"];

db.getCollection('coll').update(
    { "_id": "1234" },
    [
        { "$set": {
            "tags": {
                "$concatArrays": [
                    { "$filter": { 
                        "input": "$tags",
                        "cond": { "$not": [ { "$in": ["$$this.t", myTags] } ] }
                    } },
                    { "$map": { 
                        "input": myTags,
                        "in": {
                            "$cond": [
                                { "$in": ["$$this", "$tags.t"] },
                                { "t": "$$this", "n": { 
                                    "$sum": [
                                        { "$arrayElemAt": [
                                            "$tags.n", 
                                            { "$indexOfArray": [ "$tags.t", "$$this" ] } 
                                        ] },
                                        1
                                    ]
                                } },
                                { "t": "$$this", "n": 0 }
                            ]
                        }
                    } }
                ]
            }
        } }
    ],
    { "upsert": true }
);


  1. Hoe print je meer dan 20 items (documenten) in MongoDB's shell?

  2. Mongoose JS-query's komen allemaal terug null of leeg

  3. Hoe geneste objecten opvragen?

  4. Een lange queryreeks rechtstreeks naar MongoDB ontleden (net zoals u kunt in SQL)