查找缺少任意字段的CouchDB文档

时间:2011-05-31 05:27:59

标签: database view nosql couchdb

我需要一个CouchDB视图,在那里我可以找回所有没有任意字段的文档。如果您事先知道文档可能没有的字段,这很容易做到。 For example,这样您就可以发送view/my_view/?key="foo"以便在没有“foo”字段的情况下轻松检索文档:

function (doc) {
  var fields = [ "foo", "bar", "etc" ];

  for (var idx in fields) {
    if (!doc.hasOwnProperty(fields[idx])) {
      emit(fields[idx], 1);
    }
  }
}

但是,您只能询问视图中设置的三个字段;像view/my_view/?key="baz"这样的东西不会给你任何东西,即使你有很多文档缺少那个领域。我需要一个视图 - 我不需要事先指定可能缺少的字段。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

这项技术被称为泰式按摩。如果(并且仅当)视图键入文档ID,则使用它可以在视图中有效地查找文档而不是

function(doc) {
    // _view/fields map, showing all fields of all docs
    // In principle you could emit e.g. "foo.bar.baz"
    // for nested objects. Obviously I do not.
    for (var field in doc)
        emit(field, doc._id);
}

function(keys, vals, is_rerun) {
    // _view/fields reduce; could also be the string "_count"
    return re ? sum(vals) : vals.length;
}

要查找没有该字段的文档,

  1. GET /db/_all_docs并记住所有ID
  2. GET /db/_design/ex/_view/fields?reduce=false&key="some_field"
  3. 比较_all_docs中的ID与查询中的ID。
  4. _all_docs但不在视图中的ID是那些缺少该字段的ID。

    将ids保存在记忆中听起来很糟糕,但你不必这样做!您可以使用合并排序策略,同时迭代两个查询。首先是 has 列表的第一个id(来自视图)和完整列表的第一个id(来自_all_docs)。

    1. 如果已满< ,它缺少字段,使用下一个完整元素重做
    2. 如果完整 = ,则会显示字段,重做下一个完整元素
    3. 如果已满> ,重做,下一个元素
    4. 根据您的语言,这可能很难。但是,例如,在Javascript或其他事件驱动的编程框架中,这很容易。

答案 1 :(得分:1)

事先不知道可能的字段,答案很简单。您必须创建新视图才能找到缺少的字段。该视图将逐个扫描每个文档。

为避免干扰您现有的视图和设计文档,您可以使用全新的设计文档。这样,搜索丢失的字段不会影响您可能已在使用的现有视图。