【问题标题】:query mid-section of firebase database in swift快速查询firebase数据库的中间部分
【发布时间】:2016-05-07 09:16:54
【问题描述】:

我将 firebase 用于大型数据库,每个条目都使用 autoid 键。例如,要获取最后十个条目,我可以使用:

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'
            }
        })

并将值“final”保存为上次更新的时间码。也就是说,首先我会得到结果,例如 90-100,并将 90 的时间码保存为最终值(减去一秒),然后将其用作结束值,等等......以找到结果 80-89。 正如 Jay 在下面描述的那样,但使​​用时间戳而不是索引号(因为它已经在里面了)

编辑 2: 另外,为了让它更好地工作,我还在数据库的 firebase 规则中添加了 ".indexOn": "timecode"

【问题讨论】:

  • 有几种方法可以做到这一点,但一个超级简单的解决方案是简单地在另一个节点中保留一个 total_count 并在每个节点中保留一个索引。然后使用开始于和结束于。您还可以利用节点上的优先级变量来存储索引。您还可以使用transation 来计算您的节点数,然后使用 starter 和 end at 索引。
  • 谢谢。我对此有所了解,但无法使其正常工作。如果可能的话,我想只从顶部的键中查询。我认为我所追求的被称为“分页”,我在 iOS 上找不到简单的方法,我不知道如何使用由 autoid 键结构化的数据来做到这一点。
  • 我发布了一个答案来帮助它工作。这很简单,但如果您有任何问题,请告诉我。
  • @Richie,你的代码中的final 是什么?是数字还是时间戳?

标签: ios swift firebase firebase-realtime-database


【解决方案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 - 这仅取决于您的应用的工作方式。

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

Transitions 和 .observeSingleEvent 以及 .Value 和 .numChildren 也可用于获取活动节点数。

【讨论】:

  • 谢谢!!我使用了这个想法,但意识到我已经有一个时间码戳,所以我将其用作“索引”,如下所示: ref.queryOrderedByChild("timecode").queryEndingAtValue(final).queryLimitedToLast(10).observeSingleEventOfType(.Value ...,其中 final 是最新的时间码减去一分钟,以免重叠。我认为它现在运行良好,再次感谢!
  • 如果它有助于接受答案,但也可以用最终解决方案更新您的问题。
【解决方案2】:

您是否尝试过堆叠查询?

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

只是一个想法,哈哈。

【讨论】:

  • 好主意!但不幸的是,它会导致崩溃。我猜它限制了 100 中的最后 20 个,以及 100 中的前 10 个,它们不重叠。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 2016-11-14
  • 2012-02-16
  • 1970-01-01
  • 2018-05-23
  • 2012-02-24
相关资源
最近更新 更多