Mapreduce 为什么可以';我不能在CouchDB中删除映射函数中的属性吗?

Mapreduce 为什么可以';我不能在CouchDB中删除映射函数中的属性吗?,mapreduce,couchdb,Mapreduce,Couchdb,我在CouchDB中有一个视图和一个映射函数。我只是对数组中的一些值进行迭代,一个数组会单独发出它们。不过,我想排除我正在发送的文档的属性。我本想打电话给delete,但这似乎没什么用。该值仍随属性一起发出。为了保持索引速度,这是一个限制吗?我的映射函数如下所示: function(doc) { if (doc.type == 'user' && doc.spaces) { doc.spaces.forEach(function (space) { if

我在
CouchDB
中有一个
视图
和一个
映射
函数。我只是对数组中的一些值进行迭代,一个数组会单独发出它们。不过,我想排除我正在发送的文档的属性。我本想打电话给
delete
,但这似乎没什么用。该值仍随属性一起发出。为了保持索引速度,这是一个限制吗?我的映射函数如下所示:

function(doc) {
  if (doc.type == 'user' && doc.spaces) {
    doc.spaces.forEach(function (space) {
      if (space.tokens) {
        space.tokens.forEach(function (token) {
          emit(token.token, space);
        });
      }
    });
  }
}
在我发出
空格
的地方,我想在发出之前删除它的
标记
属性。我不想暴露此数据中的其他令牌。所以,我修改了代码,使其看起来像这样,但没有运气。它仍然会发出完整的文档,并且令牌保持不变:

function(doc) {
  if (doc.type == 'user' && doc.spaces) {
    doc.spaces.forEach(function (space) {
      if (space.tokens) {
        var tokens = space.tokens;
        delete space.tokens;
        tokens.forEach(function (token) {
          emit(token.token, space);
        });
      }
    });
  }
}

我们也被这个问题所困扰

我们通过创建一个新对象并发射它来解决这个问题:

emit(token.token, {
  name :  space.name,
  id : space.id
  etc : etc
}

我们发现这是最好的方法,因为大多数时候不需要发出完整的(子)文档,只需要发出所需的文档。

现在我也遇到了同样的问题。我正在搜索这个话题。但不幸的是,另一个答案对我没有用处。因为CouchDB不是SQL,所以文档具有不同的属性。因此,我无法使用特定属性发出
emit

经过思考,我想出了解决这个问题的办法。它在那里:

function( doc )
{
  // Remove a `seal` in the doc using a deep-copy technique.
  var tmp = JSON.parse( JSON.stringify( doc ) );

  // We can `delete` a property as we like!
  delete tmp._rev;

  // Emit `tmp`.
  emit( null, tmp );
}

这是由于“密封”:CouchDB JavaScript查询服务器使用此SpiderMonkey特性使文档在被映射函数处理时不可更改。这可以防止其他映射函数在这种状态下意外地修改文档和处理文档。更具体地说,对“密封”对象的引用是关于SpiderMonkey实现的ES5功能()的。我甚至尝试将其设置为新变量,但它似乎保持密封状态<代码>var newobject=doc不起作用的原因是因为newObject只是对同一文档对象的另一个引用。newObject指向同一个“密封”对象。您需要创建一个新对象,如上面的示例所示。