查询附近位置 [英] Query for nearby locations

查看:75
本文介绍了查询附近位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase存储用户最近一次扫描的纬度和经度.

I am using Firebase to store users with their last scanned latitude and longitude.

条目看起来像这样:

"Bdhwu37Jdmd28DmenHahd221" : {
  "country_code" : "at",
  "firstname" : "John",
  "gender" : "m",
  "lat" : 11.2549387,
  "lon" : 17.3419559
}

每当用户按下特定的搜索"按钮时,我都希望我的Firebase函数提取与发送请求的人最接近的人.

Whenever a user presses a specific "search" button, I want my Firebase function to fetch the people nearest to the person who sent the request.

由于Firebase仅允许在一个字段后进行查询,因此我决定添加country_code,以具有一定的范围限制并对该字段进行查询.但是,当我加载特定国家/地区的每个用户,然后检查给定用户与同一国家/地区中所有其他用户之间的最小距离时,速度仍然非常慢.

Since Firebase only allows for querying after one field, I decided to add the country_code, to kind of have some range-restrictions and query for that field. But it is still super slow when I load every user of a specific country and then check for the smallest distance between a given user and all the other users in the same country.

该功能已经有5位用户,大约需要40秒钟才能获得结果.

Already with 5 users, the function takes like 40 seconds to achieve the results.

我还阅读了有关复合索引的信息,但是我需要以某种方式组合纬度和经度并查询两个字段.

I have also read about compound Indexes, but I would need to somehow combine the latitude and the longitude and query for both fields.

是否有任何方法可以让这里涉及第二和第三条查询(例如,搜索相同的country_code,然后搜索相似的经度和纬度),还是必须在服务器代码中解决此问题?

Is there any way to either get a second and third query involved here (e.g. search for the same country_code, and then for a similar longitude and latitude) or do I have to solve this inside my server code ?

推荐答案

Firebase数据库只能通过单个属性进行查询.因此,过滤纬度和经度值的方法是将它们组合为一个属性.该组合属性必须保留您想要的用于数值的过滤特征,例如过滤范围的能力.

The Firebase Database can only query by a single property. So the way to filter on latitude and longitude values is to combine them into a single property. That combined property must retain the filtering traits you want for numeric values, such as the ability to filter for a range.

虽然一开始看起来似乎不可能,但实际上是以 Geohashes .它的一些特征:

While this at first may seem impossible, it actually has been done in the form of Geohashes. A few of its traits:

这是一种分层的空间数据结构,可将空间细分为网格状的桶形

It is a hierarchical spatial data structure which subdivides space into buckets of grid shape

因此:Geohashhes将空间分成多个桶网格,每个桶由一个字符串标识.

So: Geohashes divide space into a grid of buckets, each bucket identified by a string.

Geohashes具有诸如任意精度的特性,并具有从代码末尾逐渐删除字符以减小其大小(并逐渐失去精度)的可能性.

Geohashes offer properties like arbitrary precision and the possibility of gradually removing characters from the end of the code to reduce its size (and gradually lose precision).

字符串越长,存储桶覆盖的区域越大

The longer the string, the larger the area that the bucket covers

由于精度逐渐降低,附近的位置通常(但不总是)具有相似的前缀.共享前缀越长,两个位置越近.

As a consequence of the gradual precision degradation, nearby places will often (but not always) present similar prefixes. The longer a shared prefix is, the closer the two places are.

以相同字符开头的字符串彼此靠近.

Strings starting with the same characters are close to each other.

结合这些特征,您可以了解为什么这些Geohashes在Firebase数据库中如此吸引人:它们将位置的纬度和经度合并为一个字符串,在字典上彼此靠近的字符串指向该位置在身体上彼此靠近.魔术!

Combining these traits and you can see why these Geohashes are so appealing for use with the Firebase Database: they combine the latitude and longitude of a location into a single string, where strings that are lexicographically close to each other point to locations that are physically close to each other. Magic!

Firebase提供了一个名为Geofire的库,该库使用Geohashes在其实时数据库之上实现了Geolocation系统.该库可用于 JavaScript Objective-C/斯威夫特.

Firebase provides a library called Geofire, which uses Geohashes to implement a Geolocation system on top of its Realtime Database. The library is available for JavaScript, Java and Objective-C/Swift.

要了解有关Geofire的更多信息,请查看:

To learn more about Geofire, check out:

  • this blog post introducing Geofire 2
  • the .
    The app doesn't work anymore (the data isn't being updated), but the code is still available.
  • this video on how to implement geoqueries on Cloud Firestore.

这篇关于查询附近位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆