首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift - Firebase数据库查询范围的项目

Swift - Firebase数据库查询范围的项目
EN

Stack Overflow用户
提问于 2017-09-20 15:45:51
回答 1查看 339关注 0票数 0

考虑以下数据库树:

代码语言:javascript
复制
root: {
    followees: {
        <uid-1> : {
            // list of all users "uid-1" is following (each child node is a different FCM topic)
            <uid-1-1>: true, // true = subscribed to FCM topic
            <uid-1-2>: false,
            // theoretically, "uid-1" could be following millions of users, but 100k is probably a more reasonable maximum
        }
        <uid-2> : {
            // list of all users "uid-2" is following
        }
    } 
}

什么是最有效、最节省内存的方法来迭代subtree中的所有子级?

我使用限制查询创建了一个递归解决方案,每次读取1000个子数据。这是可行的,但是由于递归方面的原因,所有的子级都存储在内存中,直到它命中大小写;这与同时加载所有的子实例本质上是一样的。

我考虑过清除observeSingleEvent(.value)返回的集合,但这不起作用,因为集合是不可变的。

我能想到的最好的解决方案是查询数据库中的前1000个子数据,然后是第二个1000个,等等:

代码语言:javascript
复制
query(startIndex:0, endIndex:999)
query(startIndex:1000, endIndex:1999)
query(startIndex:2000, endIndex:2999)
...

如何使用Firebase来完成这一任务?完全可以做到吗?我的数据库结构是否应该重新设计,这样子树就不能包含数百万个条目?

如有任何建议,敬请谅解!

这是我的递归解决方案,如果你感兴趣的话。注意,它不是有效的Swift代码--它只是显示了这个概念。

代码语言:javascript
复制
func iterateChildren(startingAt: String, block: (child) -> Void) {
    // The actual query would use queryStartingAt and queryLimited.
    ref.query { children in
        // Used in recursive call.
        var nextStartingId: String? = nil

        for (index, child) in children.enumerated() {
            if (UInt(index) == limit - 1) {
                // Firebase Database's queryStarting(atValue:) method is inclusive of
                // atValue, so skip the last item as it will be included in the next
                // iteration.
                nextStartingId = child.key
                break
            }
            block(child)
        }

        if (nextStartingId != nil) {
            self.iterateChildren(startingAtId: nextStartingId, block: block)
        }   
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-20 16:06:57

而不是一个大孩子,试着使用小而简洁的孩子。为什么你不试着用逻辑把你的子孩子分组呢?

一个好的解决方案可能是按插入日期对数据进行分组(但取决于您的用例):

代码语言:javascript
复制
root : {
   child : {
      "20/09/2017" : {
          "uid" : true  
      },
      "21/09/2017" : {
          "uid" : false
          "uid" : true
      }
   }
}

使用此解决方案,您可以使用observe(.childAdded)迭代您的子节点,其中每个completionHandler都会为您提供一小块数据。

无论如何,我确定的是使用.value观察者是一个糟糕的解决方案。

火柴建议避开上帝的孩子,所以试着遵循以下简单的规则:https://firebase.google.com/docs/database/ios/structure-data

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46326492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档