如何通过firebase提高经度和纬度数据的搜索效率?

时间:2018-01-21 00:29:42

标签: firebase search firebase-realtime-database

我在firebase中有一个名为users的表,表格如下:

enter image description here

该表的结构是:

users
  |_
    uid1
     |_
       latitude: ...
       longitude: ...
       name: ...
    uid2
     |_
       latitude: ...
       longitude: ...
       name: ...

我想编写名为getUserByLocation的云函数,示例请求网址为https://someurl/getUserByLocation?latitude=40.45654&longitude=-86.68468,其中latitudelongitude为原始点,然后转到users表以查找10英里范围内的所有用户,然后将其返回。它看起来并不难,事实上,我有一些有用的东西:

  1. 计算latLowerlatUpperlongLowerlongUpper并制作如下圈: enter image description here
  2. 然后使用查询...orderByChild('latitude').startAt(latLower).endAt(latUpper).once('value')...选择latitudes在范围内的用户,此时我无法考虑longitude,因为显然我只能按一个键排序结果
  3. 检查从步骤2中选择的所有结果,如果longitude也在范围内(longLowerlongUpper之间),则应返回此用户
  4. 这种方法确实有效,但是,我在想,如果有数百万用户会怎么样?这种方法效率不高。事实上,我编写了一个脚本来创建超过100万用户,然后使用这种方法来选择用户,通常,它需要超过10秒来查看结果,这是不可接受的。

    我的问题是,在这种情况下,有什么办法可以提高搜索效率吗?我用谷歌搜索了ElasticSearch,但目前还不知道那是什么,在这种情况下可以用来改善搜索?

1 个答案:

答案 0 :(得分:2)

您可以使用GeoFire执行此操作,但您必须将坐标存储在用户的单独根节点中。像user-location这样的东西,其中每个孩子都是由GeoFire管理的用户密钥和位置。您可以使用它来更有效地查询某个位置的半径并检索边界内用户的ID - 但是,您必须获取找到的每个用户ID的用户数据。

const geofire = require('geofire');
const geoFire = new geofire(admin.database().ref('user-location'));
const geoQuery = geoFire.query({ center, radius });

let keyListener = null;
let keyLocations = {};

return new Promise((res, rej) => {
    geoQuery.on('ready', function () {
        console.log(keyLocations);
        keyListener.cancel();
        geoQuery.cancel();
        res();
    });
    keyListener = geoQuery.on('key_entered', (key, coordinates, distance) => {
        keyLocations[key] = { coordinates, distance };
    });
});