如何查询Firebase中与字符串前缀匹配的键

如何查询Firebase中与字符串前缀匹配的键,firebase,Firebase,因为firebase不支持任何空间索引,所以我使用geohash,这里有人建议使用geohash。 Geohash正在使用字符查找附近的 假设我在firebase中有w22qt4vhy1cw99qt4vdf4vcw22qt4vhzerctgeohash存储,我只想查询靠近w22qt4的geohash 怎么做 我知道firebase已经开始了。我试过了,但没有成功 更新 将geohash存储到firebase //Encode lat lng, result w22qt4vhye1c3 var g

因为firebase不支持任何空间索引,所以我使用geohash,这里有人建议使用geohash。 Geohash正在使用字符查找附近的

假设我在firebase中有
w22qt4vhy1c
w99qt4vdf4vc
w22qt4vhzerct
geohash存储,我只想查询靠近
w22qt4
的geohash

怎么做

我知道firebase已经开始了。我试过了,但没有成功

更新

将geohash存储到firebase

//Encode lat lng, result w22qt4vhye1c3
var geoHashLatLng = encodeGeoHash(lat,lng);
firebaseRef.child('/geohash/' + geoHashLatLng).set(id); 
所以在json中

  root
   - geohash
      - w22qt4vhye1c3
         - id
      - z99qt4vdf4vc
      - w22qt4vhzerct
我的问题在这里。 我只想查询从字符
w22qt4
开始的geohash。我们可以在firebase中这样做吗

更新2
startAt()
似乎不是以

示例:我有以下几个问题

geohash节点

geohash
  - a123
  - a333
  - b123
  - c123
  - d123
使用以下代码

var firebaseRef = new Firebase('https://test.firebaseio.com');
var query = firebaseRef.child('/geohash').startAt(null, 'a');
query.on('child_added', function(snapshot) {
    console.log(snapshot.name());
});
会得到这样的结果吗

startAt(null, 'a') //return a123, a333, b123, c123, d123
startAt(null, 'c123') //return c123, d123
startAt(null, 'd') //return d123
我的预期结果

startAt(null, 'a') //return a123, a333
startAt(null, 'c123') //return c123
startAt(null, 'd') //return d123
我猜startAt()将按顺序查询26个字母,但不匹配。
那么,我可以在firebase中做些什么来获得上述预期结果呢?

您可以使用普通的startAt查询来查找指定键附近的键。例如,在这种情况下,您将:

var query = firebaseRef.child("geohash").startAt(null, 'c').limit(5);
query.on("child_added", ...);
这将为您提供geoHashLatLng之后的5个元素(按词汇进行排序)

如果希望在某个指定键处结束查询,也可以这样做。例如:

var query = firebaseRef.child("geohash").startAt(null, 'c').endAt('d');

除了上述Andrew的回答之外,您希望通过geohash获得所需的效果(即,能够进行前缀查询,让您在“查询”中指定准确性,具体来说,例如geohash中每3个字符获得~+-80km)是以更细粒度和离散化的方式存储数据

因此,与您现在存储数据的方式不同,您希望通过将geohash字符串键切分为片段(我在3个字符的边界上完成了此操作,但您应该选择适当的标记化策略,以获得所需的准确性)来保存数据,并将每个片段用作子名称,如下所示:

root
  - geohash
      - w22
        - qt4
          - vhy
            - e1c
              - w22qt4vhye1c3
                - id
          - vhz
            - erc
              - w22qt4vhzerct
                - id
      - z99
          - qt4
            - vdf
              - z99qt4vdf4vc
                - id
然后,正如在您的问题中一样,当您需要获取所有以
w22qt4
开头的地理哈希时,您将对以下内容进行查询:

firebaseRef.child('/geohash/w22/qt4/')

这将为您提供
vhy
vhz
孩子,他们拥有您感兴趣的所有实际地理哈希。

您能提供一个您正在尝试的代码片段,以便我能提供更有意义的反馈吗?@AndrewLee嗨,我刚刚更新了我的问题,请看一下。您可以使用“endAt”以特定的键结束。请参阅下面对我文章的编辑。这没有得到我想要的,我再次更新了我的问题。我想这次更清楚了。请检查一下。谢谢,教授,我忘了提我不知道结局是什么。我加了一把小提琴。请看一看,我们没有办法只按前缀查询。您需要弄清楚查询应该在哪里结束。我们按字母顺序排列,所以如果你想要c*,那么你可以从c开始到d结束,然后扔掉任何与d完全匹配的。正如@AndrewLee提到的,Firebase中没有精确的{…}.prefix()查询,但是你可以在使用Geohash时完成同样的事情,你知道Geohash只包含字母数字字符,通过在结束查询中组合
startAt()
endAt()
,以及非字母数字字符。例如,要搜索前缀
abcd
,可以使用
{…}.startAt(null,'abcd').endAt(null,'abcd~'))
,它将捕获以
abcd
开头的所有地理哈希,并且不需要在客户端进行筛选。显然,在
abcd~
之后按字典顺序排序的任何键都将丢失,但这不会影响GeoHash。谢谢@RobDiMarco的帮助。你能告诉我,如果它存在于show中,在哪里可以阅读到关于这个的信息,我如何查询val在哪里子项下?我读了firebase文档。我发现
haschilds()
forEach()
。这是正确的使用方法吗?顺便问一下,我能用angularFire吗?因为我将firebase与angularjs一起使用。因为数据已经以给定的方式进行了非规范化,所以不需要应用firebase查询。您可以将侦听器附加到树中的适当级别,它将返回所返回快照中的所有子级。