更新文档时的pouchDB query()错误

时间:2018-05-29 14:41:11

标签: javascript react-native couchdb pouchdb cloudant

我们说我有这三个文件:

{ "_id": "11111", "type": "template", "name": "person" }
{ "_id": "22222", "type": "template", "name": "place" }
{ "_id": "33333", "type": "template", "name": "thing" }

我有一个云数据库,然后我有一个从该数据库同步pouchDB的设备。

这些是我要做的步骤:

  1. 我将两个数据库同步在一起。所以现在我的设备上有这个文档的最新版本。
  2. 我运行以下查询,然后我回复所有三个模板:
  3. 代码

    var template_obj = {};
    
    return device_db.query('filters/templates')
    .then((templates) => {
        for (let t of templates.rows) templates_obj[t.id] = true;
        return templates_obj;
    });
    

    过滤器/模板

    function (doc) {
      if(doc.type == "template")
        emit(doc._id);
    }
    

    返回

    { "11111": true, "22222": true, "33333": true }
    
    1. 我更新模板:云上的人。然后我再次更新它。因此,如果没有同步到我的设备,则会进行2次修订。

    2. 我与我的设备同步。

    3. 现在,当我运行相同的查询时,我只收回我编辑过的文档。这很奇怪,因为我还没有触及任何其他文件。相同的视图返回云上的预期结果,但不返回设备上的结果。
    4. 返回

      {"11111": true}
      
      1. 但是,如果我执行以下代码,则所有模板都会恢复正常,并且云中的相同_rev会显示在设备上。意味着同步成功并且视图变得混乱。
      2. 新代码

        return device_db.allDocs({conflicts: true})
        .then((data) => {
            for (let d of data.rows) {
                if(d.doc.type == "template") {
                    templates_obj[d.doc._id] = true;
                }
            }
            return templates_obj;
         }).catch((err) => {
            console.log(JSON.stringify(err));
        })
        

        我开始相信这是一个错误,因为如果我销毁我的数据库并再次执行这些步骤,我可以重现这个问题。

3 个答案:

答案 0 :(得分:1)

在意识到你正在使用React Native之后,我认为这实际上与React Native中的PouchDB有关,而且它确实是一个bug。有几种关于这种行为的报告:

答案 1 :(得分:0)

[编辑:似乎是使用React Native的PouchDB中的一个错误。我留下这个答案,因为它可能在其他方面有所帮助。]

我怀疑你正在使用的全局变量testsvy<-update(testsvy,avg2=rowMeans(testsvy$variables[,c("x1","x2","x3")],na.rm=TRUE)) 会产生一些副作用。请直接尝试template_obj,而不是将其存储在顶级作用域中的变量中,或使用console.log(templates.rows)来避免副作用。然后,您将始终获得正确的视图结果。

这是一步一步的代码:

Array.reduce()

或者更简洁的ES2015 +:

return device_db.query('filters/templates')
  .then(templates => templates.rows)            // Take only the rows into account.
  .then(rows => rows.map(row => row.id)         // Extract the id. If you wanted the name instead this would be possible with a slightly different view.
                                                // I think it would suffice to log the result right now, 
                                                // but if you really want to have a single object with boolean values, 
                                                // you can do the following:
  .then(ids => ids.reduce((asObject, id) => {   // Use Array.reduce() here to avoid any potential side effects.
    asObject[id] = true;
    return asObject;
  }, {})
  .then(asObject => { console.log(asObject); }; // Debug the result.

顺便说一下:你也可以使用其他策略“过滤”你的文件,因为没有必要发出_id。相反,您可以使用“二级索引”的键和/或值:

return device_db.query('filters/templates')
  .then(({rows}) => rows.reduce((acc, {id}) => ({...acc, [id]: true }), {}))
  .then(result => console.log(result))
  • 您也可以将docs / byType用作其他文档类型的通用视图。只需使用{ "_id": "_design/docs", "views": { "byType": "function(doc) { emit(doc.type); }", "templatesByName": "function(doc) { if (doc.type === 'template') emit(doc.name); }", "byTypeAndName": "function(doc) { emit([doc.type, doc.name], doc.name); } } }
  • 进行调用即可
  • 如果您希望按名称排序模板,请使用db.query('docs/byType', { key: 'template' })db.query('docs/templatesByName')

提醒一句:这些都是未经测试的,只是来自内存,因此代码中可能缺少一些括号,或者某些错误可能隐藏在那里。

答案 2 :(得分:0)

这不是PDB中的错误,不幸的是,pouchdb-react-native中的组件已过时。 确认的方法是像这样自己组合pouchdb-react-native-然后查询按预期工作:

import PouchDB from 'pouchdb-core';
PouchDB
.plugin(require('pouchdb-adapter-asyncstorage').default)
.plugin(require('pouchdb-adapter-http'))
.plugin(require('pouchdb-mapreduce'))
.plugin(require('pouchdb-replication'))
.plugin(require('pouchdb-authentication'));
const localDB = new PouchDB(localDBname, {adapter: 'asyncstorage', auto_compaction: true});

这样,可以确保所有组件都是最新的。