CouchDB过滤功能和连续进给

问题描述 投票:0回答:3

我有一个基于文档属性的过滤函数过滤,例如“版本:A”并且它工作正常,直到在此属性“version:A”被删除(或更新为“version:B”)的某个时间点更新文档。

此时我想通知文档已更新,类似于文档被删除时,但找不到有效的方法(没有监听和处理所有文档的更改)。

希望我只是缺少一些东西,这不是设计限制。

couchdb
3个回答
1
投票

虽然我的另一个答案是一个有效的方法,但我昨天也有同样的情况,并决定使用芒果选择器来研究这项工作。我做了以下事情:

  1. 建立由查询选择器筛选的更改提要(请参阅/ db / _changes的“_selector”筛选器)
  2. 执行查询(db / _find)并记录结果
  3. 建立第二个更改源,仅在(2)中返回的文档中进行过滤(请参阅/ db / _changes的“_doc_ids”过滤器)

(1)处的提要可以让您知道新文档何时与您的查询匹配,以及在更改之前和之后对与您的查询匹配的文档进行编辑。

(2)处的供稿可让您知道何时对先前与您的查询匹配的文档进行更改,无论该更改是否与您的查询匹配。

这些饲料的组合涵盖了所有情况,但有一些误报。在任一饲料中发生变化时,在(3)和重做步骤(2)和(3)中拆除变化饲料。

现在,关于这种方法的一些注释:

  • 这实际上仅适用于查询返回的文档数量较少的情况,因为如果在第二个Feed中按_id进行过滤。
  • 如果第一次更换进给中有大量更改,则必须小心确保正确建立第二个进给。
  • 有些情况下,两个Feed中都会出现更改。避免两次反应会很好。
  • 如果预计会经常发生变化,那么如果您的客户不需要处理每个变更通知,则采用去激活或速率限制。

这种方法对我和我必须处理的案件都很有效。

参考文献:


0
投票

您描述的行为是正确的。

CouchDB将使用使用过滤器功能完成的文档填充更改源。如果删除/修改过滤器功能使用的信息,则过滤的更改源将忽略这些更新。


0
投票

您最接近的是使用视图并根据该视图过滤更改Feed - 有关详细信息,请参阅[1]。

您可以使用地图功能创建一个包含“版本”作为键的一部分的简单视图,例如:

function (doc) {
  emit(doc.version, 1);
}

此视图筛选的更改Feed将通知您插入或删除具有“版本”字段的文档以及对现有文档的“版本”字段的更改。但是,您无法从更改Feed中确定“版本”字段的先前值。

根据您的要求,您可以使视图更具针对性。例如,如果您只关注从“A”到“B”的转换形式,那么您只能包含“A”或“B”作为其“版本”的文档:

function (doc) {
  if( doc.version === "A" || doc.version === "B") {
    emit(doc.version, 1);
  }
}

但请注意,这不会触发从“A”到“C”(或“版本”的任何其他值,包括删除文档时)的转换时的更改通知,因为更改通知仅在地图时发送function emit()至少有一个文档值。当map函数用于为给定文档发出至少一个值时,它不会通知您,但不再发生!

您还可以使用Mango选择器过滤更改Feed,因此如果Mango查询为您工作,那么这可能比使用视图更简单,但我不确定您是否可以通过Mango选择器通知删除...

编辑:

可能声称上面的简单地图功能不太正确,因为它会通知您所有文档插入和删除,而不仅仅是具有“版本”字段的文件。您可以这样做以避免一些误报通知:

function (doc) {
  if ( doc.hasOwnProperty( 'version' ) || doc.hasOwnProperty( '_deleted' ) ) {
    emit(doc.version, 1);
  }
}

这将为具有“版本”字段的新文档提供通知,或者为现有文档添加“版本”字段的更新,但它仍将通知所有删除。

[1] http://docs.couchdb.org/en/stable/api/database/changes.html#changes-filter-view

© www.soinside.com 2019 - 2024. All rights reserved.