Swift 如何在Firestore数据库中查询最近的、附近的地质点?
如何获取Firestore中的最新文档,以地理位置为半径,按时间排序 我有一个解决方案,可以获取Firestore数据库中位于指定地理位置半径内的所有文档 我需要按时间订购这些。正如你所想象的,在洛杉矶这样的地方,附近可能有10000个帖子,而我目前的解决方案无法扩展 以下是我在SWIFT 4中的Firestore查询:Swift 如何在Firestore数据库中查询最近的、附近的地质点?,swift,firebase,google-cloud-firestore,Swift,Firebase,Google Cloud Firestore,如何获取Firestore中的最新文档,以地理位置为半径,按时间排序 我有一个解决方案,可以获取Firestore数据库中位于指定地理位置半径内的所有文档 我需要按时间订购这些。正如你所想象的,在洛杉矶这样的地方,附近可能有10000个帖子,而我目前的解决方案无法扩展 以下是我在SWIFT 4中的Firestore查询: var query = docRef.whereField("geo", isGreaterThan: lesserGeopoint).whereField("geo", is
var query = docRef.whereField("geo", isGreaterThan: lesserGeopoint).whereField("geo", isLessThan: greaterGeopoint)
这足以让我得到最接近的帖子。因此,一旦我有了所有最接近的帖子,我就解析它们并将它们放入一个数组中,然后对数组进行如下排序:
self.posts.sort(by: { $0.time > $1.time })
然而,我用虚拟数据进行了规模测试,结果如下:
(N = amount of posts that are queried and loaded)
N LOAD TIME (average)
-----------------------------------
0 303 ms
1 323 ms
100 393 ms
500 637 ms
1000 1011 ms (1 second)
5000 10439 ms (10.4 seconds)
任何超过1000个附近的帖子都是不现实的。我也不能将查询限制为1000个文档,因为它在Firestore服务器上不是按时间排序的,所以它只需要取附近的1000个随机文档,然后按时间排序。但是最近可能有一篇文章没有在这一批文章中有所斩获
我如何找到一个解决方案来获取最近的、附近的帖子,并限制查询,以便我的应用程序可以扩展。您应该能够通过使用时间域进行排序并设置返回文档的数量限制来实现这一点 第一个
.whereField
必须包含第一个orderBy
字段(在您的情况下是time
)。在地理查询参数之后,按时间字段排序,然后将限制设置为(例如)10,以获得前10个结果
query=docRef.whereField(“time”,大于:0)。whereField(“geo”,大于:lesserGeopoint)。whereField(“geo”,小于:greaterGeopoint)。顺序(按:“time”)。限制(至:10)
如果将时间存储为Cloud Firestore本机时间戳(ISO8601),则需要使用whereField(“时间”,大于:“”)
更新
这个特殊的解决方案不起作用,因为您无法对两个单独的字段执行范围查询,如中所述,听说过GeoFire吗?听起来像是实时数据库的使用案例?@RonRoyston我已经使用GeoFire多次了。我的问题是问Firestore的解决方案,而不是实时数据库。另外,我不完全确定你是否读过这个问题。Geofire严格用于geoqueries,不支持按时间戳排序和限制。问题是,无论出于何种原因,Firebase都不允许我们在一个不是我们进行比较的字段上调用orderBy。例如,由于我在“geo”字段上运行了比较,所以无法按时间排序。非常令人沮丧,我知道这就是为什么您在查询的开头添加了一个.where字段作为时间字段。它不需要过滤任何东西。它只需返回所有文档,因此>0或>“”刚刚注意到,非常感谢。你是这方面的天才。'InvalidQueryException',原因:'无效查询。带有不等式(lessThan、lessThanOrEqual、greaterThan或greaterThanOrEqual)的所有where过滤器必须位于同一字段上。但在“timestamp”和“geo”上有不平等过滤器
一个新错误。我想所有的不等式子句都应该在同一个域上,我已经考虑了很多。如果使用该解决方案添加一个位置
对象,其中包含城市(键)和时间戳(值),则可以获取按时间戳排序的城市的所有文档。然后,您可以通过更精确的地理点进行过滤。不太理想,我知道。或者,如果您的地理点是固定的,您可以使用云函数将数据写入BigQuery之类的东西,然后从那里请求数据。