我在firebase中有一个名为users
的表,表格如下:
该表的结构是:
users
|_
uid1
|_
latitude: ...
longitude: ...
name: ...
uid2
|_
latitude: ...
longitude: ...
name: ...
我想编写名为getUserByLocation
的云函数,示例请求网址为https://someurl/getUserByLocation?latitude=40.45654&longitude=-86.68468
,其中latitude
和longitude
为原始点,然后转到users
表以查找10英里范围内的所有用户,然后将其返回。它看起来并不难,事实上,我有一些有用的东西:
latLower
,latUpper
,longLower
和longUpper
并制作如下圈:
...orderByChild('latitude').startAt(latLower).endAt(latUpper).once('value')...
选择latitudes
在范围内的用户,此时我无法考虑longitude
,因为显然我只能按一个键排序结果longitude
也在范围内(longLower
和longUpper
之间),则应返回此用户这种方法确实有效,但是,我在想,如果有数百万用户会怎么样?这种方法效率不高。事实上,我编写了一个脚本来创建超过100万用户,然后使用这种方法来选择用户,通常,它需要超过10秒来查看结果,这是不可接受的。
我的问题是,在这种情况下,有什么办法可以提高搜索效率吗?我用谷歌搜索了ElasticSearch
,但目前还不知道那是什么,在这种情况下可以用来改善搜索?
答案 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 };
});
});