Хобрук: Ваш путь к мастерству в программировании

Расстояние печати MongoDB между двумя точками

Когда я запускаю этот запрос в MongoDB, я получаю все места в радиусе 500 миль от указанных координат. Но я хочу знать точное расстояние между указанными координатами и местом результата.

db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()

Мой вывод выглядит так:

{
    "_id" : ObjectId("565172058bc200b0db0f75b1"),
    "type" : "Feature",
    "geometry" : {
        "type" : "Point",
        "coordinates" : [
            -80.148826,
            25.941116
        ]
    },
    "properties" : {
        "Name" : "Anthony's Coal Fired Pizza",
        "Address" : "17901 Biscayne Blvd, Aventura, FL"
    }
}

Я также хочу знать расстояние до этого места от указанной координаты. Я создал индекс 2dsphere по геометрии.


Ответы:


1

Вы можете использовать этап сводной конвейерной обработки $geoNear для получения расстояния от запрашиваемая точка:

 db.new_stores.aggregate([
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ -81.093699, 32.074673 ]
        }, 
        "maxDistance": 500 * 1609,
        "spherical": true,
        "distanceField": "distance",
        "distanceMultiplier": 0.000621371
    }}
]).pretty()

Это позволяет указать "distanceField", что создаст другое поле в выходных документах, содержащее расстояние от запрашиваемой точки. Вы также можете использовать "distanceMultiplier" для применения любого преобразования к выходному расстоянию по мере необходимости (например, метры в мили, и обратите внимание, что все расстояния GeoJSON возвращаются в метрах).

Существует также команда geoNear с аналогичными параметрами, но она, конечно, не вернуть курсор в качестве вывода.

23.11.2015
  • Большое спасибо, все работает отлично. Любопытно узнать, почему вы умножили это на 1609? 23.11.2015
  • @SiMemon Потому что в миле 1609 метров, и наоборот на множителе расстояния. Число 3963, которое вы использовали, представляет собой преобразование радианов в мили, что при использовании с координатами точек GeoJSON было бы неверным. Радианы используются только в том случае, если хранилище и запрос используют устаревшие пары координат. 23.11.2015
  • Можем ли мы найти расстояние от запрашиваемой точки до нескольких геоточек в одном запросе вместо одной? 01.10.2018
  • Может ли это определить, пересекаются ли две окружности? То есть, предположим, у меня есть коллекция, которая содержит широту и долготу, а также радиус. Поскольку GeoJSON не поддерживает круги, могу ли я написать запрос для определения расстояния между двумя точками, а затем проверить, меньше ли это расстояние суммы обоих радиусов? Будет ли это работать и будет ли это эффективно? Спасибо. 28.04.2019

  • 2

    MongoDB предоставляет агрегатор $geoNear для расчета расстояния до документов в коллекции с координатами GeoJson.

    Давайте разберемся с этим на простом примере. Рассмотрим простые коллекционные магазины

    1. Создать коллекцию

    db.createCollection('shops')
    

    2. Вставка документов в коллекции магазинов

    db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
    
    db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
    
    db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
    
    db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
    

    3. создать GeoIndex для адресных полей

    db.shops.createIndex({address: "2dsphere" } )
    

    4. Теперь используйте агрегатор $geoNear, чтобы найти документы на расстоянии.

    db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
    

    Здесь координаты:[28.411134,77.331801] — центральная позиция или требуемая позиция, откуда будут извлекаться документы.

    distanceField:shopDistance , агрегатор $geoNear возвращает shopDistance в виде полей результата.

    Результат:

    { "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
    { "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
    { "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
    { "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
    

    Здесь shopDistance будет в метрах.

    22.06.2020

    3

    maxDistance -> Необязательно. Максимальное расстояние от центральной точки, на котором могут находиться документы. MongoDB ограничивает результаты теми документами, которые находятся в пределах указанного расстояния от центральной точки.

    Укажите расстояние в метрах, если указана точка в формате GeoJSON, и в радианах, если указанная точка является устаревшей парой координат.

    В документах говорится, что если вы используете устаревшие пары, например: near: [long, lat], то укажите maxDistance в радианах. Если вы используете GeoJSON , например : near : { type : "Point" , координаты : [long ,lat] }, укажите maxDistance в метрах.

    26.05.2020
    Новые материалы

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

    ВЫ РЕГРЕСС ЭТО?
    Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

    Расистский и сексистский робот, обученный в Интернете
    Его ИИ основан на предвзятых данных, которые создают предрассудки. Он словно переходит из одного эпизода в другой из серии Черное зеркало , а вместо этого представляет собой хронику..

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..