создание или обновление с помощью _conflicts вместо 409

#javascript #couchdb #pouchdb #cloudant #couchdb-2.0

#javascript #couchdb #pouchdb #cloudant #couchdb-2.0

Вопрос:

Возможно ли put bulkDocs использовать couchdb / pouchdb или в couchdb и получить то же поведение, что и при репликации, т.Е. выигрышную ревизию _conflicts вместо 409 ответа?

В принципе, я хотел бы избежать conflict случая в следующем коде:

   const docs = Object
    .keys(pendingSet)
    .map(id => toDoc(deepClone(pendingSet[id]), { id, rev: this.revCache.get(id) }))

  const results = await this.db.bulkDocs(docs)
  const conflicts = []

  for (let n = 0; n < results.length;   n) {
    const result = results[n]
    if (result.error === 'conflict') {
      // TODO: This needs review...
      const doc = await this.db.get(docs[n]._id)
      const rev = `${doc._rev.split('-')[0]}-${this.serverName}`
      conflicts.push({
        ...docs[n],
        _rev: rev
      })
      this.revCache.set(doc._id, rev)
    } else if (result.error) {
      callback(result.error)
    } else {
      this.revCache.set(result.id, result.rev)
    }
  }

  await this.db.bulkDocs(conflicts, { new_edits: false })
 

Я получил небольшую подсказку от pouchdb, но я все еще не уверен, как ее применить.

EDIT1: обновлено с использованием последнего кода.

Ответ №1:

CouchDB пытается защитить себя от конфликтов, поэтому, если вы попытаетесь изменить редакцию документа, который CouchDB «знает», который уже был заменен, вы получите ответ 409.

Способ, которым репликации «сходит с рук», заключается в том, что документы массово записываются на целевую машину с флагом «new_edits = false». Это дает указание CouchDB не проверять токены ревизии, а принимать входящие (записи, поступающие из источника репликации, уже имеют свои собственные деревья ревизий).

Вы можете сделать это самостоятельно с помощью таких вызовов:

 ccurl -X POST -d '{"docs":[{"_id":"x","_rev":"1-myrevtoken","y":3}],"new_edits":false}' '/a/_bulk_docs'
 

В этом случае я ввел вторую «ревизию 1» в документ, в котором уже была «ревизия 2»:

 id = x
├─ 1
│  ├─ 1-myrevtoken
│  └─ 1-a6664c0114e6002415a47b18d4c9d32f
└─ 2-bca8f049e40b76dbfca560e132aa5c31 *
 

Победителем по-прежнему остается «редакция 2», но конфликт в редакции 1 остается неразрешенным, пока вы не решите его разрешить.

Комментарии:

1. Спасибо! Это помогло мне в правильном направлении. Однако вопрос. Как создается новый «myrevtoken»? Является ли это постоянным uuid для приложения?

2. Обычно токен ревизии представляет собой хэш содержимого документа. Но это зависит от вас.

3. Опечатка — должно быть new_edits=false (не true ) во втором абзаце.

Ответ №2:

С помощью CouchDB вы можете all_or_nothing: true задать запрос _bulk_docs. Это создает новые ревизии независимо от конфликтов. При new_edits: false этом вы не получаете новую редакцию, которая имеет смысл для репликации, но, возможно, нет, если вы на самом деле отправляете обновление документа. PouchDB не имеет опции all_or_nothing в своих bulkDocs.