MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB - $set за актуализиране или натискане на елемент Array

Всъщност да направите това, което изглежда, сякаш казвате, че правите, не е единствена операция, но ще разгледам частите, необходими, за да направя това или по друг начин да обхвана други възможни ситуации.

Това, което търсите, е отчасти позиционния $ оператор. Имате нужда от част от вашата заявка, за да "намерите" и елемента от масива, който искате.

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

Така че $ означава съвпадащата позиция в масива, така че частта за актуализиране да знае кой елемент в масива да актуализира. Можете да получите достъп до отделни полета на документа в масива или просто да посочите целия документ за актуализиране на тази позиция.

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

Ако полетата всъщност не се променят и просто искате да вмъкнете нов елемент от масива, ако същият не съществува, тогава можете да използвате $addToSet

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

Ако обаче просто търсите "натискане" към масив от единствена ключова стойност, ако тя не съществува, тогава трябва да направите още малко ръчна обработка, като първо видите дали елементът в масива съществува и след това направите $push изявление, когато не е така.

Получавате помощ от методите на mongoose за това, като проследявате броя на документите, засегнати от актуализацията:

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) {

                }
            );
        }            

    }
);

Единствената дума за предупреждение тук е, че има малка промяна в реализацията в съобщенията writeConcern от MongoDB 2.6 към по-ранни версии. В момента не сте сигурни как API на mongoose всъщност изпълнява връщането на numAffected аргумент в обратното извикване разликата може да означава нещо.

В предишни версии, дори ако данните, които сте изпратили в първоначалната актуализация, съвпадат точно със съществуващ елемент и не е била необходима реална промяна, тогава „променената“ сума ще бъде върната като 1 въпреки че всъщност нищо не е актуализирано.

От MongoDB 2.6 отговорът за притеснение при запис съдържа две части. Едната част показва модифицирания документ, а другата показва съвпадението. Така че докато съвпадението ще бъде върнато от частта на заявката, съответстваща на съществуващ елемент, действителният брой на модифицираните документи ще се върне като 0 ако всъщност не е била необходима промяна.

Така че в зависимост от това как действително е внедрен номерът за връщане в mongoose, всъщност може да е по-безопасно да използвате $addToSet оператор на тази вътрешна актуализация, за да се уверите, че ако причината за нулевите засегнати документи не е просто, че точният елемент вече съществува.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. В mongoDb, как премахвате елемент от масива по неговия индекс?

  2. Получаване на резултат $group с брой групи

  3. Изпълнение на Mongo като Query (JSON) чрез Java

  4. Закръгляване до 2 знака след десетичната запетая с помощта на рамката за агрегиране на MongoDB

  5. Производителността на MongoDB при заявки за агрегиране