2015-12-18 59 views
2

我想知道如何使用Geofire过滤器进行查询。 假设我有不同类别的餐厅。我想将该类别添加到我的查询中。我如何去做这件事?我现在已经与Geofire查询键使用Geofire + Firebase过滤结果

的一种方式,通过每个键运行for循环,并得到了餐厅,并插入相应的餐厅阵列。 这些效率很低。有没有其他方法可以解决这个问题?

理想情况下,我将获得过滤结果,并且只在每个项目即将显示时才加载。

干杯!

+0

Firebase查询只能过滤一个条件。 Geofire已经做了相当的“魔术”,让它能够在经度和纬度上进行过滤。为该等式添加另一个属性可能是可能的,但远远超出了Geofire默认处理的范围。见http://stackoverflow.com/questions/34084347/geofire-how-to-add-extra-conditions-within-the-query(我认为是重复的)。 –

+0

好的,那么你如何过滤其他条件? – ordinaryman09

+0

这取决于:如果您一次只想访问一个类别,则可以将餐厅放在每个类别的顶级节点中,并将Geofire指向一个类别。但更常见的是,您只需在客户端代码中进行额外的过滤。如果您担心其性能:测量它,分享代码,JSON数据和测量结果。 –

回答

8

Firebase查询只能过滤一个条件。 Geofire已经完成了相当一些"magic"以允许它在经度和纬度上进行过滤。为该等式添加另一个属性可能是可能的,但远远超出了Geofire默认处理的范围。请参阅GeoFire: How to add extra conditions within the query?

如果您只想一次访问一个类别,则可以将餐厅放在每个类别的顶级节点中,并将Geofire指向一个类别。

/category1 
    item1 
     g: "pns0h0mf2u" 
     l: [-53.435719, 140.808716] 
    item2 
     g: "u417k3dwub" 
     l: [56.83069, 1.94822] 
/category2 
    item3 
     g: "8m3rz3s480" 
     l: [30.902225, -166.66809] 
/items 
    item1: ... 
    item2: ... 
    item3: ... 

在上面的例子中,我们有两个类别:category1与2项和category2只有1个项目。对于每个项目,我们都会看到Geofire使用的数据:地理哈希和经度和纬度。我们还保留了这三个项目的其他属性的单一列表。

但更常见的是,您只需在客户端代码中进行额外的筛选。如果您担心其性能:测量它,分享代码,JSON数据和测量结果。

+0

我明白了。似乎通过客户端过滤它并不复杂。谢谢! – ordinaryman09

+0

如果我有帮助,upvote我的答案。如果我回答了您的问题,请点击左侧的复选标记。 –

3

这是一个老问题,但我已经在网络上的一些地方看到它,所以我想我可能会共享一个把戏我用。

的问题

如果你在你的数据库中收集了大量的,也许包含成千上万的钥匙,例如,它可能不是抢他们全部是可行的。如果你想根据除其他标准位置来筛选结果,你坚持的东西,如:

  1. 执行位置查询
  2. 循环每一个返回geofire键,抢在相应的数据数据库
  3. 检查每个返回的数据块,看它是否在其他条件

不幸的是,这是一个很大的网络请求,这是相当缓慢的匹配。

更具体地说,假设我们想让所有用户都在100英里的男性和年龄在20到25之间的特定位置。如果在100英里内有10,000个用户,这意味着需要10,000个网络请求来获取用户数据并比较他们的性别和年龄。

的解决方法:

你可以存储你需要在geofire密钥本身的比较,用分隔符的数据。然后,您可以拆分geofire查询返回的键以访问数据。您仍然需要通过它们进行筛选,但它比发送数百或数千个请求要快得多。

例如,你可以使用以下格式:

UserID*gender*age,这可能看起来像facebook:1234567*male*24。最重要的点是

  1. 独立的数据点由分隔符
  2. 使用的分隔符有效字符 - “它可以包括除了任何Unicode字符$#[] /和ASCII控制字符0-31和“127.)”
  3. 使用一个不会在数据库的其他地方找到的字符 - 我使用*,但这可能对您不适用。请勿使用-ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz中的任何字符,因为这些对于由Firebase生成的密钥是公平的游戏。push()
  4. 为数据选择一致的顺序 - 在此情况下,先选择UserID,然后选择性别,然后选择年龄。

您可以将最多768 bytes of data存储在火力点钥匙中,这很有帮助。

希望这有助于!

+0

Firebase使用websockets,这消除了此解决方法的需要,是吗?问题不在于你做了多少请求,因为你只创建一个套接字,一个关闭。问题在于过滤数据,如数据集中包含数千和数千条目的数据,这可能很重。我认为最好的方法是以一种可以索引到节点和更好地排序子节点的方式来构建数据。 – jhm

+0

伟大的答案!谢谢! – MCMatan

+0

@jhm你能详细说明怎么做吗? ZenPylon的方法我的问题是,即使地球另一端的某个人更新了分支,每次更改时都必须运行该过滤器。这是超级不理想,所以我想知道最好的方法是什么。 – AlxVallejo