CouchDB过滤器功能和连续供稿

时间:2018-09-06 15:32:44

标签: couchdb

我有一个基于文档属性进行过滤的过滤器功能,例如“版本: A ”,并且可以正常工作,直到在某个属性点“版本: A ”被删除(或更新为“版本: B ”)。

在这一点上,我想收到有关文档已更新的通知,类似于删除文档时的更新,但是找不到有效的方法(不监听和处理所有文档更改)。

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

3 个答案:

答案 0 :(得分:1)

虽然我的另一种答案是有效的方法,但昨天我遇到了同样的情况,并决定考虑使用Mango选择器进行这项工作。我做了以下事情:

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

(1)的供稿可让您知道新文档何时与您的查询匹配,以及在更改前后对与您的查询匹配的文档所做的编辑。

(2)中的feed可以让您知道何时对先前与您的查询匹配的文档进行了更改,而无论更改之后是否与您的查询匹配。

这些供稿的组合涵盖了所有情况,尽管有一些误报。如果更改了任一提要,请在(3)处拆下更改提要,然后重做步骤(2)和(3)。

现在,有关此方法的一些注意事项:

  • 这真的仅适用于查询返回的文档数较少的情况,因为如果第二个提要中使用_id进行过滤。
  • 如果第一个变更摘要中有很多变更,则必须小心以确保正确建立第二个摘要。
  • 在某些情况下,两个Feed中都会出现更改。最好避免两次反应。
  • 如果预计更改会频繁发生,那么如果您的客户不需要处理每一个更改通知,请使用防抖或速率限制。

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

参考文献:

答案 1 :(得分:0)

您描述的行为是正确的。

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

答案 2 :(得分:0)

您最接近的是使用一个视图并基于该视图过滤更改摘要-有关详细信息,请参见[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”的转换(或“ version”的任何其他值,包括删除文档时)的更改通知,因为仅发送更改通知当地图函数的emit()是文档的至少一个值时。当映射函数用于发出给定文档的至少一个值,但不再发出通知时,它不会通知您!

您还可以使用Mango选择器过滤更改供稿,因此,如果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