Різниця між набором із {merge: true} та оновленням


115

У Cloud Firestore є три операції запису:

1) додати

2) встановити

3) оновлення

У документах сказано, що використання set(object, {merge: true})об'єднає об'єкт із існуючим.

Те ж саме відбувається при використанні. update(object) Яка різниця, якщо така є? Дивно здається, що Google буде дублювати логіку.

Відповіді:


263

Те, як я зрозумів різницю:

  • setбез mergeбуде перезаписати документ або створити його, якщо він ще не існує

  • setз mergeоновить поля в документі або створить його, якщо його не існує

  • update оновить поля, але вийде з ладу, якщо документа не існує

  • create створить документ, але не вдасться, якщо документ вже існує

Існує також різниця у типі даних, які ви надаєте setта update.

Для setвас завжди повинні надавати дані документа в формі:

set(
  {a: {b: {c: true}}},
  {merge: true}
)

З updateвами також можна використовувати шляхи поля для оновлення вкладених значень:

update({
  'a.b.c': true
})

1
але де ви знайшли createметод в API?
ZuzEL

2
cloud.google.com/nodejs/docs/reference/firestore/0.8.x/… для node.js. Здається, веб-API такого методу не має. Не був впевнений, на якій платформі ви знаходитесь :)
Scarygami

10
Ще одна відмінність, яку ви можете згадати, - це те, що setдіє на документах у формі документа, де updateприймаються пара поля шляху та значення. Це означає, що ви можете внести зміни до глибоко вкладених значень, updateякі є більш громіздкими set. Наприклад: set({a: {b: {c: true}}}, {merge: true})проти update('a.b.c', true).
Гіл Гілберт

Якщо я хочу оновити значення в документі, має сенс, що я хочу оновити документи, які вже існують, тому я думаю, що встановити + mergeall не є корисним, тому що він створить його, документа не існує
Джон Балвін Аріас

Якщо дані, які ви надаєте команді set, мають поле, яке є нульовим, чи встановить це поле на нульове значення, якщо воно вже присутнє в базі даних, чи залишить його в спокої?
користувач1023110

71

Інша відмінність (розширення відповіді Скарігамі) між "встановити злиттям" та "оновити", полягає в роботі з вкладеними значеннями.

якщо у вас такий документ структурований:

 {
   "friends": {
     "friend-uid-1": true,
     "friend-uid-2": true,
   }
 }

і хочете додати {"friend-uid-3" : true}

використовуючи це:

db.collection('users').doc('random-id').set({ "friends": { "friend-uid-3": true } },{merge:true})

це призведе до цих даних:

 {
   "friends": {
     "friend-uid-1": true,
     "friend-uid-2": true,
     "friend-uid-3": true
   }
 }

проте updateвикористовуючи це:

db.collection('users').doc('random-id').update({ "friends": { "friend-uid-3": true } })

це призведе до цих даних:

 `{
   "friends": {
     "friend-uid-3": true
   }
 }`

1
Ви самі пробували тестувати це? У документації є розділ: "Для оновлення деяких полів документа, не перезаписуючи весь документ, використовуйте метод update () ..."
Finlay Percy

2
Я зрозумів це. Я раніше пробував це лише з масивом. Де я хотів додати об’єкт до масиву, і все було перезаписано для цього масиву. Він не працює з полями, що містять масив ... він дійсно витримує документи.
ravo10

1
Просто дійшов до того ж висновку після тестів. Сподіваюся, вони додадуть параметр, який має такий же ефект, як і { merge: true }для функції оновлення.
Джонріда

1
Дякую за цю відповідь! Приклади, хоча й прості, зробили його більш чистим, ніж прийнята відповідь, яка з них була кращою для моєї справи.
naiveai

2
Щоб уникнути перезапису даних у вкладені поля (як у відповіді вище) під час використання update, ви можете використовувати позначення крапок . Поведінка перезапису updateвідрізняється, якщо ви робите / не використовуєте позначення крапок.
Тедковський

7

За документами: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

Нотація точок дозволяє оновити одне вкладене поле без перезаписання іншого вкладеного поля. Якщо ви оновите вкладене поле без позначок крапки, ви перезаместите все поле карти.

Як було сказано вище, це замінює всю структуру друзів.

db.collection('users').doc('random-id').update({
    "friends": {
        "friend-uid-3": true
    }
})

Це не так.

db.collection('users').doc('random-id').update({
    "friends.friend-uid-3": true
})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.