如何删除Firebase节点中除最近X个孩子以外的所有子项?

时间:2015-11-24 07:27:12

标签: firebase

如果Firebase节点lines填充了唯一ID子项(来自push()操作),例如:

Firebase--
  --lines
    --K3qx02jslkdjNskjwLDK
    --K3qx23jakjdz9Nlskjja
    --K3qxRdXhUFmEJdifOdaj
    --etc...

我希望能够删除lines 的所有子项,但最近添加的200(或100,或其他)。基本上这是一个清理操作。现在我知道我可以通过抓取客户端lines的所有子项的快照,计算条目,然后使用endsAt(totalChildren-numToKeep)获取相关数据并运行remove()来实现此目的。但我想避免将所有数据都抓到客户端。

上面我的想法有替代方案吗?

1 个答案:

答案 0 :(得分:3)

保留最新的N项,是实施的棘手用例之一。如果您有任何选择将其更改为“保留过去N小时内的项目”,我建议您选择该路线。

用例很棘手的原因是你在计算项目,而Firebase(故意)没有任何基于计数的操作。因此,您需要检索前N个项目以了解哪个项目是N + 1。

ref.child('lines').once('value', function(snapshot) {
  if (snapshot.numChildren() > MAX_COUNT) {
    var childCount = 0;
    var updates = {};
    snapshot.forEach(function (child) {
      if (++childCount < snapshot.numChildren() - MAX_COUNT) {
        updates[child.key()] = null;
      }
    });
    ref.child('lines').update(updates);
  }
});

这里需要注意的一些事项:

  • 这将下载所有行
  • 执行单个update()调用以删除无关的行

优化此方法的一种方法(除了选择不同的/基于时间的截断策略)是保留单独的“行ID”列表。

lineids
  --K3qx02jslkdjNskjwLDK
  --K3qx23jakjdz9Nlskjja
  --K3qxRdXhUFmEJdifOdaj

因此,您仍会保留lines中每一行的数据,但会保留一份ID列表。然后删除额外的代码变为:

ref.child('lineids').once('value', function(snapshot) {
  if (snapshot.numChildren() > MAX_COUNT) {
    var childCount = 0;
    var updates = {};
    snapshot.forEach(function (child) {
      if (++childCount < snapshot.numChildren() - MAX_COUNT) {
        updates['lineids/'+child.key()] = null;
        updates['lines/'+child.key()] = null;
      }
    });
    ref.update(updates);
  }
});

这个最后一个片段稍微复杂一些,但是不必通过下载行ID来下载所有行数据。

您可以选择许多变体,但我希望这可以作为入门的足够灵感。