sql >> Databáze >  >> NoSQL >> MongoDB

mongoDB upsert na pole

Ve skutečnosti to není tak jednoduché, jak si možná myslíte, a ve skutečnosti je zajímavé, že jste svou analýzu rozdělil do tří částí. Protože, hádejte co? To je přesně to, co musíte dělat. Zvažme kroky:

1. Vložte dokument, pokud neexistuje

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

Takže to, co chcete udělat, je vložit nový dokument, kde "clientId" aktuálně neexistuje. To lze provést jako „upsert“, aby se předešlo možným jedinečným střetům klíčů, a dokonce i tam, kde neexistuje žádné „jedinečné“ omezení, pak „upsert“ povaha tohoto zajistí, že vytvoříte „nový“ dokument pouze tehdy, když nebyl nalezen. Existuje také $setOnInsert zde, protože neděláte chcete udělat cokoli s dokumentem, který je v tomto okamžiku „nalezen“.

Všimněte si, že zde není ne pokusit se porovnat prvek v poli. Je to proto, že pravděpodobně nechcete „vytvářet“ nový dokument jen proto, že existující dokument neměl „ten“ prvek pole. Což nás přivádí k dalšímu kroku.

2. Aktualizujte obsah dokumentu tam, kde existuje

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

Nyní zde chcete skutečně zkusit „přiřadit“ dokument k „clientId“, které dělá obsahovat prvek v poli, který také odpovídá hledanému "deviceId". Takže zadáním podmínky, která se má shodovat, získáte použití pozičního $ operátora, aby se pole nastavila do "odpovídající" pozice.

Jak je uvedeno výše, toto buď odpovídalo jedničce věc nebo nic takže buď aktualizace proběhla, nebo ne. Takže se přesouváme k naší poslední části kaskády zde:

3. Přidejte prvek pole tam, kde neexistuje

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

Takže to je důležité poslední etapa. Důvodem je to, že pokud některá z předchozích operací provedla "vytvořit" nebo "aktualizovat" existující dokument a poté použít $addToSet zde ujišťuje „netlačíte“ další dokument do pole se stejným „deviceId“, ale jinými odlišnými hodnotami. Pokud jeden z těchto fází fungovalo, pak by to vidělo, že všechny hodnoty tohoto prvku již existují, a pak by se nepřidávala další.

Pokud byste to zkusili udělat v jiném pořadí, v případě, který uvádíte, měli byste dva dokumenty v poli se stejným "deviceId", ale odlišnými hodnotami pro "deviceType" a "notification". Proto je to poslední.

Závěr

Takže bohužel neexistuje jednoduchý způsob, jak je spojit jako jeden úkon. Operátory prostě neexistují, aby to šlo udělat v jediném příkazu, a proto musíte provést tři aktualizovat operace, abyste mohli dělat, co chcete. Také, jak je uvedeno, objednávka aplikace pro tyto aktualizace je důležité abyste dosáhli požadovaného výsledku.

I když to zatím v aktuálních „produkčních“ vydáních neexistuje, nadcházející vydání (2.6 a vyšší v době psaní) nabízí způsob, jak tyto požadavky „dávkovat“ novou syntaxí k aktualizaci:

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

Takže zatímco to je stále v podstatě tři operace, alespoň je můžete poslat po drátě jen jednou



  1. Jak spravovat dokumenty v MongoDB

  2. Automatické zvýšení v MongoDB pro uložení sekvence jedinečného ID uživatele

  3. Odlišná hodnota počtu MongoDB?

  4. převod databáze z mysql na mongoDb