如何检索文档的不同属性

How to retrieve distinct properties of documents

在我们的 CouchDB 文档数据库中,我们有具有不同 "status" 属性 值的文档,如下所示:

doc1: {status: "available"},
doc2: {status: "reserved"},
doc3: {status: "available"},
doc4: {status: "sold"},
doc5: {status: "available"},
doc6: {status: "destroyed"},
doc7: {status: "sold"}
[...]

现在,我想编写一个 map-reduce 函数,returns 所有文档中存在的所有 distinct 状态值:["available", "reserved", "sold", "destroyed"].

我的方法是开始编写一个映射函数,该函数 returns 只有每个文档的 "status" 属性:

function (doc) {
  if(doc.status) {
    emit(doc._id, doc.status);
  }
}

现在,我想比较所有地图行,这样就不会返回重复的状态。

official CouchDB documentation 似乎非常详细和技术性,但不能真正投射到我们的用例中,它没有像博客文章中那样的任何嵌套结构,而是简单的 "flat objects" 和 "status" 属性。此外,我们的后端使用 PouchDB 作为适配器来连接到我们的远程 CouchDB。

我发现当执行下面的 reduce 函数时(我自己实现了这个函数试图理解幕后发生的事情),会返回一些奇怪的结果。

function(keys, values, rereduce) {
  var array = [];

  if(rereduce) {
    return values;
  } else {
    if(array.indexOf(values[0]) === -1) {
      array.push(values[0]);
    }
  }

  return array;
}

结果:

{
  "rows": [
    {
      "key": null,
      "value": "[reduce] [status] available,available,[status] sold,unknown,[status] available,[status] available,[status] available,reserved,available,[status] reserved,available,[status] available,[status] sold,reserved,[status] sold,sold,[status] available,available,[status] reserved,[status] reserved,[status] available,[status] reserved,available"
    }
  ]
}

reduce步骤似乎只执行一次,而status循环有时只有一个值,然后是两个或三个值,没有可识别的逻辑或模式。

有人可以向我解释以下内容吗:

  1. 如何检索具有所有不同状态值的数组
  2. CouchDB reduce 功能的逻辑(或工作流程)是什么?为什么 status 行具有任意数量的状态值?

感谢@chrisinmtown 的评论,我能够使用以下函数实现状态值的不同检索:

function map(doc) {
  if(doc.status) {
    emit(doc.status, null);
  }
}
function reduce(key, values) {
  return null;
}

发送查询参数group = true也很重要,否则结果将为空:

// PouchDB request
return this.database.query('general/all-status', { group: true }).pipe(
  map((response: PouchDB.Query.Response<any>) => response.rows.map((row: any) => row.key))
);

有关如何使用视图和查询的更多信息,另请参阅 official PouchDB documentation