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

mongoDB upsert върху масив

Това всъщност не е толкова просто, колкото може би си мислите, и всъщност е интересно, че сте разделили анализа на това на три части. Защото познайте какво? Точно това е, което виетрябвате направи. Нека разгледаме стъпките:

1. Поставете документ, ако не съществува

db.collection.update(
    { 
        "clientId":"123456"
    },
    {
        "$setOnInsert": {
            "clientId": "123456",
            "devices": [{
                "deviceId": "321",
                "deviceType" : "kindle",
                "notification" : false
            }]
        }
    },
    { "upsert": true }
)

Така че това, което искате да направите, е вмъкване нов документ, където "clientId" в момента не съществува. Това може да се направи като "upsert", за да се избегнат възможни уникални сблъсъци на ключове и дори когато няма "уникално" ограничение, тогава естеството на "upsert" на това гарантира, че създавате "нов" документ само когато не е намерен. Също така има $setOnInsert тук, защото виенете искате да направите нещо с документ, който е "намерен" в този момент.

Обърнете внимание тук, че нямане опитайте се да съпоставите елемента в масива. Това е така, защото вероятно не искате да "създавате" нов документ, само защото съществуващ не е имал "този" елемент на масива. Което ни води до следващата стъпка.

2. Актуализирайте съдържанието на документа, където съществува

db.collection.update(
    { 
        "clientId":"123456",
        "devices": { "$elemMatch": { "deviceId" : "321" } }
    },
    {
        "$set": {
            "devices.$.deviceType" : "kindle",
            "devices.$.notification" : false
        }
    }
)

Сега тук искате действително да опитате да „съпоставите“ документа за „clientId“, който прави съдържа елемент в масива, който също съответства на "deviceId", който търсите. Така че, като посочите условие за съвпадение, вие получавате използването на позиционния $ оператор, за да зададете полетата в позиция "съвпадение".

Както по-горе, това или щеше да съответства на едно нещо илинищо така че или актуализацията е направена, или не. Така че това преминава към нашата последна част от каскадата тук:

3. Добавете елемента на масива, където не съществува

db.collection.update(
    { 
        "clientId":"123456"
    },
    {
        "$addToset": { "devices": {
            "deviceId" : "321",
            "deviceType" : "kindle",
            "notification" : false
        }}
    }
)

Така че това еважно последния етап. Причината е, че ако някоя от предходните операции направи „създайте“ или „актуализирайте“ съществуващия документ, след което използването на $addToSet тук прависигурно вие не "бутате" друг документ към масива със същия "deviceId", но с други различни стойности. Акоедно от тези етапи работи, тогава това ще види, че всички стойности на този елемент вече съществуват, и след това няма да добави още един.

Ако се опитате да направите това в различен ред, в случая, който представяте, ще имате два документи в масива със същия "deviceId", но различни стойности за "deviceType" и "notification". Затова е последен.

Заключение

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

Въпреки че това все още не съществува в текущите „производствени“ издания, предстоящата версия (2.6 и нагоре към момента на писането) има начин да „групира“ тези заявки с нов синтаксис за актуализиране:

db.runCommand(
    "update": "collection",
    "updates": [
        { 
            "q": { "clientId":"123456" },
            "u": {
                "$setOnInsert": {
                    "clientId": "123456",
                    "devices": [{
                    "deviceId": "321",
                    "deviceType" : "kindle",
                    "notification" : false
                }]
            },
            "upsert": true
        },
        {
            "q": { 
                 "clientId":"123456",
                 "devices": { "$elemMatch": { "deviceId" : "321" } }
            },
            "u": {
                "$set": {
                    "devices.$.deviceType" : "kindle",
                    "devices.$.notification" : false
                 }
            }
        },
        {
            "q": { "clientId":"123456" },
            "u": {
                "$addToset": { "devices": {
                    "deviceId" : "321",
                    "deviceType" : "kindle",
                    "notification" : false
                }}
            }
        }
    ]
)

Така че докато това е все още по същество три операции, поне можете да ги изпратите по кабела само веднъж



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Кога да затворите връзката с базата данни MongoDB в Nodejs

  2. Съкращаване на колекция

  3. Проверете удостоверяването на MongoDB с драйвер за Java 3.0

  4. Как ефективно да изтриете документи чрез заявка в mongo?

  5. 7 начина за броене на документи в MongoDB