哪个更快:视图或 allDocs Array.filter?

which is faster: views or allDocs with Array.filter?

我想知道 CouchDb/PouchDb 中的专用视图与仅检索 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'});

有什么更好的? 2种方法各有什么优缺点?

视图的使用将更好地扩展。但是 "faster" 取决于很多因素,您需要针对您的硬件、网络和数据的特定情况进行基准测试。

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

对于"view"的情况,B-Tree索引用于查找匹配文档的范围。只将匹配的文档发送给客户端,因此网络时间和内存的节省取决于所有文档中匹配文档的比例。时间复杂度为 O(log(N) + M),其中 N 是文档总数,M 是匹配文档的数量。

如果 N 很大而 M 很小,那么这种方法应该受到青睐。随着 M 接近 N,两种方法几乎相同。如果 M 和 N 未知或高度可变,请使用视图。

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

Mango 查询可能也比此类查询的视图更有趣。如果数据集大小允许,您可以在 "type" 字段上创建索引,但这不是强制性的。

就个人而言,我会使用 Mango 查询并添加必要的索引 if/when。