MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

mongoDB upsert na tablicy

To nie jest tak proste, jak mogłoby się wydawać, i faktycznie interesujące jest, że podzieliłeś swoją analizę na trzy części. Bo wiesz co? Właśnie to musisz robić. Rozważmy kroki:

1. Wstaw dokument, jeśli taki nie istnieje

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

Więc to, co chcesz zrobić, to wstawić nowy dokument, w którym „clientId” obecnie nie istnieje. Można to zrobić jako „upsert”, aby uniknąć możliwych unikalnych kolizji kluczy, a nawet tam, gdzie nie ma „unikalnego” ograniczenia, „upsert” zapewnia, że ​​utworzysz „nowy” dokument tylko wtedy, gdy nie zostanie znaleziony. Istnieje również $setOnInsert tutaj, ponieważ nie chcesz zrobić wszystko z dokumentem, który został „znaleziony” w tym momencie.

Zwróć uwagę, że nie ma nie spróbuj dopasować element w tablicy. Dzieje się tak, ponieważ prawdopodobnie nie chcesz „tworzyć” nowego dokumentu tylko dlatego, że istniejący nie ma „tego” elementu tablicy. Co prowadzi nas do następnego kroku.

2. Zaktualizuj zawartość dokumentu tam, gdzie on istnieje

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

Teraz chcesz spróbować „dopasować” dokument do „identyfikatora klienta”, który robi zawierać element w tablicy, który również pasuje do "deviceId", którego szukasz. Zatem określając warunek do dopasowania, uzyskujesz użycie pozycyjnego $ operatora, aby ustawić pola w pozycji "dopasowania".

Jak wyżej, to albo będzie pasować do jednego rzecz lub nic więc albo aktualizacja została wykonana, albo nie. To przenosi się do naszej ostatniej części kaskady tutaj:

3. Dodaj element tablicy tam, gdzie nie istnieje

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

Więc to jest ważne ostatni etap. Powodem jest to, że jeśli któraś z poprzednich operacji zrobiła "utwórz" lub "zaktualizuj" istniejący dokument, a następnie użyj $addToSet tutaj daje pewność nie „wypychasz” innego dokumentu do tablicy z tym samym „deviceId”, ale innymi różnymi wartościami. Jeśli jeden z tych etapów zadziałało, wtedy wszystkie wartości tego elementu już istnieją i nie zostaną dodane kolejne.

Gdybyś próbował to zrobić w innej kolejności, w przypadku prezentowania miałbyś dwa dokumenty w tablicy z tym samym „deviceId”, ale różnymi wartościami „deviceType” i „notification”. Dlatego jest ostatni.

Wniosek

Więc niestety nie ma prostego sposobu na połączenie ich w jeden operacja. Operatory po prostu nie istnieją, więc można to zrobić w jednym oświadczeniu, dlatego musisz wykonaj trzy aktualizuj operacje, aby robić to, co chcesz. Jak również stwierdzono, zamówienie wniosków o te aktualizacje jest ważne aby uzyskać pożądany rezultat.

Chociaż nie istnieje to jeszcze w bieżących wydaniach „produkcyjnych”, nadchodzące wydanie (od wersji 2.6 wzwyż) ma możliwość „zgrupowania” tych żądań za pomocą nowej składni do aktualizacji:

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

Więc póki to jest wciąż zasadniczo trzy operacje, przynajmniej możesz je wysłać przez sieć tylko raz



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Dlaczego mój schemat nie dodaje wartości domyślnych w tablicach mangusty?

  2. Przykładowe operatory MongoDB

  3. mongodb - Znajdź dokument z najbliższą liczbą całkowitą

  4. Haszowanie hasła Mongoose

  5. Połączenie MongoDb odrzucone