Работа с геоданными в mongodb

33
Работа с геоданными в MongoDb Марк Заславский, [email protected]

Upload: osll

Post on 13-Apr-2017

683 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: Работа с геоданными в MongoDb

Работа с геоданными в MongoDb

Марк Заславский, [email protected]

Page 2: Работа с геоданными в MongoDb

О чем будет доклад

● Обзор:– Короткое знакомство с Mongo

– Коротко про GeoJson

– Какие данные можно хранить в Mongo

– Как хранить геоданные в Mongo

– Как индексировать геоданные

– Как выполнять запросы к данным (поиск объектов рядом/внутри/на пересечении с областями)

● Примеры использования геовозможностей MongoDb в Geo2Tag

Page 3: Работа с геоданными в MongoDb

Примеры к докладу

● Ссылка для скачивания: http://bit.ly/1OHMY0N

● В архиве текстовые файлы со списками комманд для каждого примера

● Решетки (#) это не комментарий в Mongo, их нужно удалить

● Примеры проверялись на MongoDb 2.4.9

Page 4: Работа с геоданными в MongoDb

(Вопросы в зал)

Page 5: Работа с геоданными в MongoDb

Введение и мотивация

● Геоданные:– часто (но не всегда) = bigdata,

– имеют сложные алгоритмы анализа/обработки,

– могут иметь сложную структуру (границы областей, маршруты).

● Mongo– из коробки умеет работать с геоданными,

– хорошо масштабируется,

– представление геоданных стандартизовано (GeoJSON).

Page 6: Работа с геоданными в MongoDb

Короткое введние в Mongo

● MongoDb – документо-ориентированная СУБД

● Данные хранятся в BSON (почти JSON)

● Документы объединяются в коллекции

● У коллекций нет обязательной схемы

● MapReduce● Полнотекстовый поиск

Page 7: Работа с геоданными в MongoDb

Коллекции и документы

● Примерное соответствие с SQL СУБД:– Коллекция = таблица

– Документ = запись в таблице

– Идентификатор _id (обязательное поле документа) = первичный ключ

● Коллекции и базы данных создаются “ленивым образом”

Page 8: Работа с геоданными в MongoDb

Пример CRUD 1mongo_crud.txt

$ mongo test_db

> db.test_collection.insert({key1:'val1', key2:'val2'})

> db.test_collection.insert({key3:'val3'})

> db.test_collection.find({key3:'val3'})

> db.test_collection.find()

> db.test_collection.remove({key3:'val3'})

> db.test_collection.find()

> db.test_collection.update({ "key1" : "val1", "key2" : "val2" }, {$set: {"key1" : "val2"}})

Page 9: Работа с геоданными в MongoDb

Формат GeoJSON

● Надмножество JSON для хранения точек, ломаных и многоугольников (а также их совокупностей (гладких кривых нет:)).

● Не накладывает ограничение на тип координат (плоские, сферические, параболические ...).

● Координаты точки задаются в виде массива

[x , y]

Или

[долгота, широта]

Page 10: Работа с геоданными в MongoDb

Наглядные примеры

● https://ru.wikipedia.org/wiki/GeoJSON#.D0.9E.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D1.8B

Page 11: Работа с геоданными в MongoDb

Наглядные примеры

● https://ru.wikipedia.org/wiki/GeoJSON#.D0.9E.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D1.8B

Page 12: Работа с геоданными в MongoDb

GeoJSON - инструменты

● Генерация GeoJSON по карте - http://geojson.io/

● Валидатор - http://geojsonlint.com/● Бьютификатор -

https://jsonformatter.curiousconcept.com/

● Описание стандарта – http://geojson.org/

Page 13: Работа с геоданными в MongoDb

Как сохранить геоданные в БД● Форматы:

– legacy coordinate pairs (только точки) [x,y]

– GeoJson (точки, линии, полигоны ...)

● Нет контроля типов у полей координат

● Одно поле = один формат представления

● Можно сохранять как в отдельное поле, так и во вложенное

Page 14: Работа с геоданными в MongoDb

Сохранение геоданных в БД – пример 2location_writing.txt

$ mongo test_db> db.test_collection1.insert({ name: '1', location : { "type" : "Point", "coordinates" : [ 1.0, 1.0 ] }})> db.test_collection2.insert({ name: '2', location : [ 1.0, 1.0 ]})

Page 15: Работа с геоданными в MongoDb

Пространственные индексы - преамбула

● Индексы – ускорение запросов.● Разные геометрии:

– Плоская (евклидово расстояние)– Сферическая WGS84,

http://spatialreference.org/ref/epsg/4326/)

http://www.colorado.edu/geography/gcraft/notes/datum/gif/geoid2.gif

Page 16: Работа с геоданными в MongoDb

Пространственные индексы

● 2dsphere– Сферическая геометрия, GeoJSON или legacy

coordinate pairs

– Можно делать связанный индекс с несколькими полями

● 2d– Плоская геометрия, legacy coordinate pairs

– Связанный индекс только с одним полем

● geoHaystack– 2d + одно не геополе, быстрее на малых площадях

чем 2d

Page 17: Работа с геоданными в MongoDb

Пример - Создаем индекс 3indexes_creation.txt

> db.test_collection1.createIndex({

location: '2dsphere'})

> db.test_collection2.createIndex({

location: '2d'})

# Проверяем индексы

> db.system.indexes.find()

Page 18: Работа с геоданными в MongoDb

$geoWithin и $geoIntersects

● Что это:– Критерии для поиска (могут быть частью сложного

запроса)

– Поиск либо объектов внутри (geoWithin), либо на пересечении с областью (geoIntersects)

– Работает для всех геометрий и типов задания координат

● Особенности– Индекс не нужен

– Есть проблема с ооочень большими областями фильтрации

Page 19: Работа с геоданными в MongoDb

$geoWithin и $geoIntersects

● Что приходит в ответ - список документов без сортировки

● Как можно искать: – Сферическая геометрия: $geometry,

$centerSphere

– Плоская геометрия: $box, $polygon, $center

Page 20: Работа с геоданными в MongoDb

Пример про $geoWithin 4geowithin.txt

db.test_collection1.find( { location : { $geoWithin : { $geometry : { type : "Polygon" , coordinates : [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] # Замыкаем фигуру ] ] } } } } )

Page 21: Работа с геоданными в MongoDb

Пример про $geoWithin 4geowithin.txt

db.test_collection1.find( { location :

{ $geoWithin :

{ $centerSphere:

[ [1, 1], # Центр

2] # Радиус в радианах

}}})

Page 22: Работа с геоданными в MongoDb

Пример про $geoIntersects 4geointersects.txt

db.test_collection1.find( { location :

{ $geoIntersects :

{$geometry:

{"type": "LineString",

"coordinates": [ [0, 1], [1, 1] ]

}

}

}

})

Page 23: Работа с геоданными в MongoDb

$near и $nearSphere

● Что это: операторы поиска объектов, близких к точке.

● Особенности– Near – использует евклидово расстояние,

nearSphere – сферическое.

– Требует наличия любого геоиндекса.

– Нельзя комбинировать со сложными запросами, требующими специальный индекс

– Можно задать пределы расстояний.

Page 24: Работа с геоданными в MongoDb

$near и $nearSphere

● Что приходит в ответ: отсортированные по расстоянию документы

● Единицы измерения расстояний зависят от того, как задана точка отсчета:– GeoJSON – метры

– Legacy pair - радианы

Page 25: Работа с геоданными в MongoDb

Пример - поиск точек по расстоянию 5nearsphere.txt

db.test_collection1.find( { location :

{ $nearSphere:

{ $geometry :

{ type : "Point",

coordinates : [ 0, 0 ]}, # Точка отсчета

$maxDistance : 190000} # В метрах

}

})

Page 26: Работа с геоданными в MongoDb

Операции аггрегирования

● примерный аналог группировки в SQL базах данных

● выбираем данные по критерию и работаем с ними:– группируем дальше ( можно делать

многоступенчатую аггрегацию)

– меняем формат

– создаем новые поля на основании вычислений в текущих (минимум, среднее, максимум и тд)

Page 27: Работа с геоданными в MongoDb

$geoNear

● Аналог near/nearSphere – но на этапе аггрегации

● Требует наличия одного геоиндекса● Не нужно указывать поле с координатами ● Может быть только первым этапом

аггрегирования● Нельзя использовать одновременно с near*,

но можно geoWithin/Intersect

Page 28: Работа с геоданными в MongoDb

$geoNear пример – 6geonear.txt

db.test_collection1.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [ 1 , 1.0000001 ] }, distanceField: "dist.calculated", # Название нового поля для записи расстояния maxDistance: 2, # Максимальное расстояние до точки query: {name:"1"} , # ЗАпрос с дополнительной фильтрацией includeLocs: "dist.location", # Новое поле, где будут дополнительно выведены координаты spherical: true } } ])

Page 29: Работа с геоданными в MongoDb

GeoHaystack Index + geoSearch

● GeoHaystack ориентирован на:– Запросы сначала по непространственному полю,

а затем по пространственному

– Данные из ограниченной области

● команда geoSearch - аналог geoNear для коллекций с geoHaystack индексом

Page 30: Работа с геоданными в MongoDb

Пример использования GeoSearch 7geosearch.txt

> db.test_collection3.insert({ _id : 100, pos: { lng : 126.9, lat : 35.2 } , type : "restaurant"})

> db.test_collection3.insert({ _id : 200, pos: { lng : 127.5, lat : 36.1 } , type : "restaurant"})

> db.test_collection3.insert({ _id : 300, pos: { lng : 128.0, lat : 36.7 } , type : "national park"})

Page 31: Работа с геоданными в MongoDb

Пример использования GeoSearch 7geosearch.txt

db.test_collection3.createIndex( { pos : "geoHaystack", type : 1 } ,{ bucketSize : 1 } )

db.runCommand( { geoSearch : "test_collection3" ,

search : { type: "restaurant" } ,

near : [-74, 40.74] ,

maxDistance : 1000 } )

Page 32: Работа с геоданными в MongoDb

Реальное использование в Geo2Tag

● Geo2Tag – платформа для создания геоконтекстных сервисов

● Геоданные – отдельные точки (широта, долгота, высота) с привязанным описанием/ссылкой

● REST интерфейс для поиска точек по вхождению в пространственную область

● Индексирование через 2dSphere ● Запрос GeoWithin + запросы поиска по

высоте и параметрам описания

Page 33: Работа с геоданными в MongoDb

Что почитать

● Хороший туториал от создателей БД по геовозможностям https://docs.mongodb.org/manual/tutorial/geospatial-tutorial/

● Индексы, типы геометрий https://docs.mongodb.org/manual/applications/geospatial-indexes/

● Введение в Mongo http://jsman.ru/mongo-book/

● Формат GeoJSON http://geojson.org/