sql >> Database >  >> NoSQL >> MongoDB

MongoDB - $set om het Array-element bij te werken of te pushen

Eigenlijk doen wat u zegt te doen, is geen enkelvoudige handeling, maar ik zal de onderdelen doornemen die nodig zijn om dit te doen of anderszins andere mogelijke situaties te behandelen.

Wat u zoekt is gedeeltelijk de positionele $ exploitant. Je hebt een deel van je query nodig om ook het element van de array te "vinden".

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$.vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Dus de $ staat voor de overeenkomende positie in de array, zodat het updategedeelte weet welk item in de array moet worden bijgewerkt. U kunt toegang krijgen tot individuele velden van het document in de array of u kunt gewoon het hele document specificeren om op die positie bij te werken.

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Als de velden in feite niet veranderen en u wilt gewoon een nieuw array-element invoegen als exact hetzelfde niet bestaat, dan kunt u $addToSet gebruiken

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        $addToSet:{ 
            "recentviews": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Als u echter alleen op zoek bent naar "duwen" naar een array met een enkelvoudige sleutelwaarde, als die niet bestaat, moet u wat meer handmatige handelingen uitvoeren, door eerst te kijken of het element in de array bestaat en vervolgens de >$push verklaring waar dit niet het geval is.

U krijgt hierbij wat hulp van de mangoestmethoden door het aantal documenten bij te houden dat door de update is beïnvloed:

Product.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    },
    function(err,numAffected) {

        if (numAffected == 0) {
            // Document not updated so you can push onto the array
            Product.update(
                { 
                    "_id": ObjectId("536c55bf9c8fb24c21000095")
                },
                { 
                    "$push": { 
                        "recentviews": {
                            "viewedby": "abc",
                            "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
                        }
                    }
                },
                function(err,numAffected) {

                }
            );
        }            

    }
);

De enige waarschuwing hier is dat er een kleine implementatiewijziging is in de writeConcern-berichten van MongoDB 2.6 naar eerdere versies. Op dit moment niet zeker weten hoe de mangoest-API de terugkeer van de numAffected daadwerkelijk implementeert argument in de callback kan het verschil iets betekenen.

In eerdere versies, zelfs als de gegevens die u in de eerste update stuurde exact overeenkwamen met een bestaand element en er geen echte wijziging nodig was, zou het "aangepaste" bedrag worden geretourneerd als 1 ook al is er eigenlijk niets bijgewerkt.

Vanaf MongoDB 2.6 bestaat het antwoord over schrijven uit twee delen. Het ene deel toont het gewijzigde document en het andere toont de overeenkomst. Dus terwijl de overeenkomst zou worden geretourneerd door het zoekgedeelte dat overeenkomt met een bestaand element, zou het werkelijke aantal gewijzigde documenten worden geretourneerd als 0 als er in feite geen verandering nodig was.

Dus afhankelijk van hoe het retournummer daadwerkelijk is geïmplementeerd in mangoest, kan het veiliger zijn om de $addToSet te gebruiken operator op die innerlijke update om ervoor te zorgen dat als de reden voor de nul getroffen documenten niet alleen was dat het exacte element al bestond.




  1. Zoeken in mongo db met behulp van mangoest regex vs. tekst

  2. MongoDB $bestaat

  3. Wil je Redis gebruiken als een opslag voor evenementenstatistieken

  4. Hoe gebruik je spring data mongo @CompoundIndex met subcollecties?