如何删除 Firebase 节点中除最近的 X 子节点之外的所有子节点?

Posted

技术标签:

【中文标题】如何删除 Firebase 节点中除最近的 X 子节点之外的所有子节点?【英文标题】:How to delete all but most recent X children in a Firebase node? 【发布时间】:2015-11-24 07:27:11 【问题描述】:

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

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

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

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

【问题讨论】:

【参考方案1】:

保留最近的 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);
  
);

最后一个 sn-p 稍微复杂一些,但无需通过仅下载线路 ID 来下载所有线路数据。

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

【讨论】:

以上是关于如何删除 Firebase 节点中除最近的 X 子节点之外的所有子节点?的主要内容,如果未能解决你的问题,请参考以下文章

如何从特定的 UICollectionViewCell 中删除 firebase 子节点 - Swift

Firebase -- 批量删除子节点

删除节点 Firebase 下的所有项目

flutter firebase 如何获取节点的所有子节点

如何从 firebase 数据库参考中获取子节点列表?

如何使用两个子值在 Firebase 中进行搜索?