Заказывать запрос Firestore GeoHash от ближайшего к самому дальнему?

В настоящее время я использую части библиотеки GeoFirebase вместе с Firestore, чтобы разрешить геозапросы. Когда я устанавливаю геохеш поста, я делаю это как таковой if let geoHash = GFGeoHash(location: location.coordinate).geoHashValue {

Однако, чтобы сделать запрос геохеша менее конкретным, я планирую обрезать часть геохеша при запросе; в настоящее время запрос выглядит примерно так

 var geoQuerySpecific = GFGeoHashQuery()
        let geoQueryHash =  GFGeoHashQuery.queries(forLocation: (lastLocation?.coordinate)!, radius: (30)) as! Set<GFGeoHashQuery>

        for query in geoQueryHash {
            geoQuerySpecific = query
            print("the key is this um \(geoQuerySpecific)")
        }
        print("the starting value is \(geoQuerySpecific.startValue)  and the end value is \(geoQuerySpecific.endValue)")
        let nearQuery = Firestore.firestore().collection("stuff").order(by: "g").whereField("g", isGreaterThanOrEqualTo: geoQuerySpecific.startValue).whereField("g", isLessThanOrEqualTo: geoQuerySpecific.endValue)

Как видите, это не будет работать правильно, поскольку в geoQueryHash есть несколько элементов. Я думал об усечении последних четырех цифр / букв из геохеша, когда я устанавливаю его в firebase, однако это не будет достаточно конкретным. Чтобы получить самые близкие сообщения, было бы лучше установить geoHash в базе данных, как я сейчас, затем, при извлечении материала, сделайте начальное значение наиболее конкретным геохешем для запроса, а затем сделайте конечное значение равным усеченная версия геохеша, чтобы начать с получения самых близких постов и закончить самыми широкими?

Я могу ограничить запрос Firestore до 50, чтобы затем я мог получить 50 сообщений от ближайшего до самого дальнего ... правильно ли я понимаю геохеширование? Возможно ли это?

По идее, если бы существовал способ хранить геохеши в виде целых чисел, я мог бы сделать так, чтобы запрос firestore начинался с наибольшего целого числа (т.е. наиболее точного геохеша), а затем обрабатывал бы запрос по убыванию, пока он не дойдет до наименее точного значения интенсификации (самого широкого геохеша). а затем ограничьте его до 50.


person Raim Khalil    schedule 20.05.2019    source источник


Ответы (1)


GeoFirestore использует геохеши, чтобы иметь возможность выбирать документы, которые находятся в диапазоне геохешей, который примерно совпадает с областью на карте. Невозможно получить эти документы в указанном порядке из этой области с помощью простого геозапроса. Если вы хотите, чтобы документы были отсортированы по расстоянию, вам нужно будет сделать это после геозапроса в коде вашего приложения.

Если вы хотите узнать больше о том, почему это так, посмотрите мой доклад недавно: Запросы Firebase и Firestore в зависимости от географического положения или расстояния. В нем я объясняю, как работают геохеши, как они позволяют выбирать документы в определенном географическом диапазоне и почему вы не можете выполнить более сложный запрос в Firestore (или исходной базе данных Firebase в реальном времени).

person Frank van Puffelen    schedule 20.05.2019
comment
Я понимаю этот аспект, но рассматриваю их с точки зрения буквенно-цифровых строк, которые можно сортировать. Например, если бы я начал с gh67, это была бы самая общая область, но если бы я пошел на gh674df5, это было бы более конкретным. С этой точки зрения, невозможно ли выполнить запрос, начиная с gh674df5 и заканчивая gh67? Можно ли таким образом отсортировать буквенно-цифровые строки? - person Raim Khalil; 20.05.2019
comment
В некоторых крайних случаях вы можете выбрать подобный поддиапазон, но не в целом. Но также не обязательно возвращать предметы от ближайшего к самому дальнему. - person Frank van Puffelen; 20.05.2019
comment
Таким образом, в принципе нет возможности запросить от ближайшего к самому дальнему, даже если я сортирую по разной длине Geohashes? - person Raim Khalil; 20.05.2019
comment
Все геохеши в документе имеют одинаковую длину. Вы можете добавить несколько геохешей к каждому документу, каждый для определенного разрешения. Но для этого варианта использования это все равно не поможет. - person Frank van Puffelen; 20.05.2019
comment
Что, если, например, каждый раз, когда пользователь публикует сообщения, я получаю его geoHash, допустим, он состоит из 9 цифр. Я могу хранить 9-значную версию геохеша, 8-значный префикс, 7-значный префикс, 6, 5 и так далее. Затем, когда я запрашиваю сообщения, я могу получить текущий геохеш пользователя и запросить его. Если документов недостаточно, так как я хочу заполнить фид, я сбрасываю одну цифру и запрашиваю 8-значный префикс геохеша, что-то вроде postsReference.whereField("(geoHash), isGreaterThan:"").limitTo(50), а затем, если этот запрос не возвращает 50 документов, перехожу к более широкому geoHash. - person Raim Khalil; 20.05.2019
comment
Для дальнейшего уточнения, например, postsReference.whereField("(geoHash9digit), isGreaterThan:"").limitTo(50), затем postsReference.whereField("(geoHash8digit), isGreaterThan:"").limitTo(50), затем postsReference.whereField("(geoHash7digit), isGreaterThan:"").limitTo(50) - person Raim Khalil; 20.05.2019
comment
в качестве альтернативы, поскольку это может привести к повторным наблюдателям (сначала сообщение наблюдает за конкретным геохешем, и оно все еще там, когда вы уменьшаете масштаб), что, если бы я вместо этого выполнял поиск. Сначала я запрашиваю квадрат, в котором находится пользователь, он не работает, затем запрашиваю геохеш над ним, под ним справа и слева, и если это все еще не работает, добавьте больше наблюдателей для геохешей вокруг них? - person Raim Khalil; 20.05.2019
comment
Недостаточно хранить разрешение с несколькими разрешениями, поскольку центр вашего запроса редко совпадает с центром геохеша. Но хранение нескольких разрешений - это, по сути, то, что делает такое решение, как S2. - person Frank van Puffelen; 20.05.2019
comment
Спасибо за вашу помощь. Имеет ли смысл эта структура? Когда пользователь публикует сообщения, получите его геохеш и 8 окружающих его геохешей. Добавьте первый геохеш в качестве поля как geohash1: primary. Затем я могу добавить остальные 8 геохешей как geohash2: secondary, geohash 3: secondary. Когда пользователь запрашивает, я могу сначала запросить местоположения с первичным, что означает, что оно было опубликовано в том же геохеше. Если ничего не возвращается, могу ли я использовать геохеш для любых сообщений, у которых геохеш пользователя является вторичным? - person Raim Khalil; 20.05.2019
comment
Мне очень сложно рассуждать о геохешах абстрактно, поэтому определенно рекомендую попробовать. Если вы идете по этому пути, обратите внимание на S2, который решает крайние случаи геохешей вокруг полюсов, больше ориентирован на несколько разрешений и снижает количество перечитываний, которые имеют все решения. - person Frank van Puffelen; 20.05.2019
comment
извините, и последнее. Можно ли с помощью S2 выполнять запросы, аналогичные запросу в моем вопросе (начиная с определенной точки, а затем постепенно выходя из нее)? Так работает S2, где я могу заказать его, например, с 109876 на 10987637? - person Raim Khalil; 20.05.2019