Musisz dostarczyć wiele kluczy do $set
z pozycyjnym $
operator
aby zaktualizować oba dopasowane klucze.
Wolę nowoczesny sposób manipulacji obiektami ES6:
let params = { "_id" : "xxxproductid", "name" : "xxx", "img" : "yyy" };
let update = [
{ 'store.products._id': params._id },
{ "$set": Object.keys(params).filter(k => k != '_id')
.reduce((acc,curr) =>
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
{ })
}
];
User.update(...update,callback);
Co spowodowałoby wywołanie MongoDB jako ( z mongoose.set('debug', true)
) włączone, więc widzimy żądanie:
Gdzie w zasadzie bierzesz swoje dane wejściowe params
i podaj _id
jako pierwszy argument dla "zapytania" :
{ 'store.products._id': params._id },
Reszta pobiera „klucze” z obiektu przez Klucze.obiektów
co tworzy „macierz”, którą możemy „filtrować” za pomocą Array.filter()
a następnie przejdź do Array. zmniejsz
aby przekształcić te klucze w obiekt
.
Wewnątrz .reduce()
nazywamy Object.assign()
która "scala" obiekty z podanymi kluczami, wygenerowanymi w tej postaci:
Object.assign(acc,{ [`store.products.$.${curr}`]: params[curr] }),
Użycie składni szablonu do przypisania „bieżącego” (curr) „klucza” do nowej nazwy klucza, ponownie używając Składnia przypisywania klawiszy ES6 []:
co pozwala na nazwy zmiennych w literałach obiektowych.
Wynikowy "scalony" obiekt jest przekazywany z powrotem w celu przypisania do obiektu "root", gdzie $set
jest używany jako klucz aktualizacji, więc „wygenerowane” klucze są teraz jego dziećmi.
Używam tablicy dla argumentów wyłącznie do celów debugowania, ale pozwala to również na czystszą składnię rzeczywistego .update()
za pomocą "rozkładania" ...
operator do przypisania argumentów:
User.update(...update,callback);
Czysty i prosty oraz kilka technik JavaScript, których powinieneś się nauczyć, aby manipulować obiektami i tablicami. Głównie dlatego, że zapytanie MongoDB DSL to w zasadzie "Obiekty" i "Tablice". Więc naucz się nimi manipulować.