2016-05-07 45 views
1

我对大型数据库使用firebase,每个条目都使用自动密钥。为了得到,比如说,过去的十个条目,我可以使用:在swift中查询firebase数据库的中间部分

ref.queryLimitedToLast(10).observeSingleEventOfType(.Value, withBlock: { snapshot in 
      for item in snapshot.children { 
       //do some code to each item 
      } 
     }) 

但是,我不能为我的生活工作如何再拿到之前的十个条目。例如。如果数据库有100个条目,我的代码将返回90-100,但是我怎样才能得到条目80-90(例如,没有查询过去的20个并抛弃一半,因为它似乎效率低下)?

编辑: 我结束了使用

ref.queryOrderedByChild("timecode").queryEndingAtValue(final).queryLimitedToLast(10).observeSingleEventOfType(.Value, withBlock: { snapshot in 
for item in snapshot.children { 
       //do some code to each item, including saving a new value of 'final' 
      } 
     }) 

和保存价值“最终”的最后一次更新的时间代码。也就是说,首先我会得到90-100的结果,并将90的时间码保存为最终的(减1秒),然后将其用于结尾值等等以找到结果80-89。 正如周杰伦介绍如下,但使用时间戳,而不是一个索引号的(因为它已经在那里)

编辑2: 此外,得到它的工作好,我还添加了“.indexOn”:“时间码“到数据库的firebase规则

+0

有几种方法可以做到这一点,但一个超级简单的解决方案是简单地将total_count保留在另一个节点中,并在每个节点中保留索引。然后使用开始和结束于。您也可以在您的节点上使用优先级变量来存储索引。您还可以使用[转换](https://www.firebase.com/docs/web/guide/saving-data.html#section-transactions)对您的节点进行计数,然后使用starter并结束索引。 – Jay

+0

谢谢你。我已经有了一个破解,但不能得到它的工作。如果可能的话,我只想从顶部的键进行查询。我想我后来被称为“分页”,我无法在iOS上找到一种简单的方法,但我不知道如何使用由自动键构造的数据来完成此任务。 – Richie

+0

我发布了一个答案,以协助它的工作。这很简单,但是如果你有问题,请告诉我。 – Jay

回答

1

有几种方法可以做到这一点,但一个简单的解决方案是保持total_count在另一个节点和每个节点内的索引。

然后使用queryStartingAtValue和queryEndingAtValue查询你感兴趣的子节点的范围。

当您添加一个孩子的“帖子”节点例如,添加一个到TOTAL_COUNT节点和保存。随着时间的推移,您将有100个帖子,而total_count节点的值将为100.然后,您可以查询任何范围的帖子:.queryStartingAtValue(80)和。 queryEndingAtValue(89),或.queryStartingAt(20)和.queryEndingAt(30)

例如,假设有45个(这里示出只是其中4)

posts 
    ... 
    post_1024 
    text: "my post!" 
    index: 42 
    post_1025 
    text: "another post" 
    index: 43 
    post_1026 
    text: "yippee" 
    index: 44 
    post_1027 
    text: "Stuff and Things" 
    index: 45 

,然后跟踪它们的节点

post_info 
    total_count: 45 

和代码查询用于中间两个节点

let ref = myRootRef.childByAppendingPath("posts" 
ref.queryOrderedByChild("index").queryStartingAtValue(43).queryEndingAtValue(44) 
    .observeEventType(.Value, withBlock: { snapshot in 
    print(snapshot.key) 
}) 

和输出将

post_1025 
    text: "another post" 
    index: 43 
    post_1026 
    text: "yippee" 
    index: 44 

话虽这么说,这可能取决于如何处理自己的数据是略显多余。如果你永远不会删除帖子,那么你就设置好了。但是,如果删除帖子,那么很明显,您的索引中存在差距(42,43,... 45),因此需要考虑其他因素。

您甚至可能不需要total_count - 这取决于您的应用程序的工作方式。

您还可以利用节点上的优先级变量来存储索引,而不是将其作为子节点。

使用.Value和.numChildren进行转换和.observeSingleEvent也可用于获取活动节点计数。

+0

谢谢!我用这个想法,但意识到我已经有一个时间码戳,所以我用它作为'索引',就像这样:ref.queryOrderedByChild(“timecode”)。queryEndingAtValue(final).queryLimitedToLast(10).observeSingleEventOfType(.Value ...,最后是最新的时间码减去一分钟,以便不重叠,我认为它现在运行良好,再次感谢! – Richie

+0

如果它帮助接受答案,并且用最终的解决方案更新您的问题 – Jay

+0

Thanks Jay ,完成! – Richie

1

您是否尝试过堆叠查询?

ref.queryLimitedToLast(20).queryLimitedToFirst(10).observeSingleEventOfType(.Value, withBlock: { snapshot in 
    for item in snapshot.children { 
     //do some code to each item 
    } 
}) 

只是一个想法,哈哈。

+0

不错的主意!但不幸的是它会导致崩溃。我猜想它限制了100人中的最后20人,以及100人中的前10人,这并不重叠。 – Richie