哪个更快:使用Array.filter的views或allDocs?

时间:2018-09-11 06:14:40

标签: couchdb pouchdb

我想知道CouchDb / PouchDb VS中专用视图之间的性能差异,只是稍后检索allDocs并使用Array.prototype.filter对其进行过滤。

假设我们要获取存储在数据库中的5,000个待办事项文档。

// Method 1: get all tasks with a dedicated view "todos"

// in CouchDB
function (doc) { 
  if (doc.type == "todo"){
      emit(doc._id);
  }
}

// on Frontend
var tasks = (await db.query('myDesignDoc/todos', {include_docs: true})).rows;


// Method 2: get allDocs, and then filter via Array.filter

var tasks = (await db.allDocs({include_docs: true})).rows;
tasks = tasks.filter(task => {return task.doc.type == 'todo'});

有什么更好的?这两种方法各自的优缺点是什么?

1 个答案:

答案 0 :(得分:1)

使用视图将更好地缩放。但是哪个“更快”取决于很多因素,您将需要针对特定​​情况在硬件,网络和数据上进行基准测试。

对于“ all_docs”情况,您将有效地将整个数据库传输到客户端,因此随着数据库的增长,网络速度将成为一个很大的因素。如果您按原样进行操作,则将所有文档放入数组中然后进行过滤,您将在某个时候达到内存使用限制-您确实需要将结果作为流进行处理。这种方法是O(N),其中N是数据库中的文档数。

对于“视图”情况,B树索引用于查找匹配文档的范围。仅将匹配的文档发送到客户端,因此节省的网络时间和内存取决于所有文档中匹配的文档的比例。时间复杂度为O(log(N)+ M),其中N为文档总数,M为匹配文档数。

如果N大而M小,则应该采用这种方法。当M接近N时,两种方法几乎相同。如果M和N未知或变化很大,请使用视图。

您应该考虑另一件事-您是否需要返回整个文档?如果您只需要大型文档中的几个字段,则视图可以只返回这些字段,从而进一步减少了网络和内存使用量。

芒果查询也可能比这种查询的视图更有趣。如果数据集大小允许,则可以在“类型”字段上创建索引,但这不是强制性的。

我个人会使用Mango查询并在必要时添加索引。