这是我在尝试将地理位置与Firestore混合时遇到的问题。长话短说-我需要用户所在地附近的餐厅。为了完成地理搜索,我使用Algolia。当我向Algolia发出请求时,它返回一个与Firestore文档id相对应的唯一餐厅id数组。这很管用。
使事情变得复杂的是,我还需要两个条件-我需要将查询限制在平均评分>=8的餐厅。我还想限制返回文档的数量(2、5、20等)。
所以在伪代码中应该是这样的:

db.restaurantsCollection
    .documentIds([111, 222, 333, 444, 555, 666, 777, 888, 999])
    .whereField("averageRating", isGreaterThanOrEqualTo: 8)
    .order(by: "averageRating", descending: true)
    .limit(to: 2)
    .getDocuments()

我知道到目前为止,Firestore不支持使用多个文档id的查询。那么,执行这种查询的最佳方法是什么?
如果我在文档中将documentId设置为id字段,然后遍历Algolia返回的所有id并执行类似的操作(然后我可以使用纯Swift进行排序和限制):
for id in ids {
    db.restaurantsCollection
        .whereField("averageRating", isGreaterThanOrEqualTo: 8)
        .whereField("id", isEqualTo: id)
        .getDocuments()
}

但这仍然意味着很多要求。还有其他想法吗?

最佳答案

如果这对任何人都有帮助,我张贴的选项,你可能会考虑,如果你是实现地理查询的方式,我实现他们-用Algolia。所以使用Algolia的方法是保持搜索索引的坐标。
例如:

{
  "_geoloc": {
    "lng": 8.507785799999999,
    "lat": 47.17652589999999
  },
  "objectID": "1234abcd"
}

objectID对应于餐厅的文档ID或您想要地理查询的任何类型的场所。
然后通过Algolia API创建查询。如果你想得到一个CLLocation周围的所有项,你应该设置它-为此使用query.aroundLatLng属性。您还可以以米为单位设置distance属性。结果将是一个JSON,您的id按距离排序,从最近的开始。
到目前为止很好-我们解决了最大的问题-按地理位置查询。
如果我想从我从Algolia得到的所有N个ID中获得最高评价呢?可悲的是,到目前为止还没有API可以通过多个id进行查询。所以这意味着如果我想得到所有得分>=8的餐厅,我需要让N个Firestore文档读取,然后获得最高评价。远非理想。
选择1。
用Algolia数据保存餐厅平均值。
我知道这意味着额外的网络,但这是一个好办法。缺点-每次更新Firestore中的餐厅平均值时,还需要更新Algolia中的餐厅平均值。如果你像我一样用云函数计算平均值,你也需要用Algolia来设置它们。是的,这意味着您需要升级到付费的Firebase计划,因为这是一个外部云功能调用。
现在,您的Algolia负载中已经有了平均值,您可以轻松地获取您所在地区的所有餐厅id,然后根据其Algolia评级客户端对数据进行排序。一旦对id进行了排序,就可以从Firestore请求文档。
选择2。
保存城市名称和国家
您可以将城市和国家名称与您的位置数据一起保存在Firestore中。这样您就可以使用它们进行查询。伪Firestore查询代码:
db.restaurants.where("city" == "current_city").where("country" == "current_country").where("averageRating" >= 8).getDocuments()

然而,这种方法并不十分准确,而且主要适用于大城市。它也不会计算接近你的位置。
我希望这能有帮助。

10-08 13:46
查看更多