Эксперименты с MongoDB


Решил поэкспериментировать, что будет работать быстрее с пространственными данными: новомодная NoSQL MongoDB или "классика" PostgreSQL/PostGIS?
NoSQL, в том числе, хороши в работе с большими объёмами данных. Правда с использованием кластера с несколькими инстансами СУБД. Всё что я смог создать большого это 10 миллионов точек в GRASS GIS: 30 секунд на настройку и несколько минут на создание набора точек. Затем экспорт этого набора в PostgreSQL 9.3/PostGIS 2.0.1, а от туда через GeoJSON в MongoDB 2.6. Файл с GeoJSON весит 1,6 Гб. Для обоих наборов были созданы пространственные индексы.


Затем я создал маленький проект, где есть сервер на NodeJS и frontend с Leaflet, так было в нагугленном примере, я бы выбрал бы OpenLayers, наверно так и сделаю на дальнейшем.

На данный момент реализовано:
  • подключение к MongoDB посредством mongojs.
  • пространственный запрос к MongoDB из Leaflet с передачей текущего охвата карты и возвращению попавших в него точек.
  • отображение в Leaflet всего этого безобразия (см. рисунок ниже)
Что нужно сделать:
  • повторить всё для  PostgreSQL/PostGIS, благо что соответствующие модули для NodeJS есть.
  • сравнить тайминги получения данных из разных типов БД в браузере.

Ясно, что все 10 млн. точек показывать не нужно, странная задача, ещё если вспомнить про размер GeoJSON.
В запросе можно указывать максимальное количество возвращаемых объектов, в данный момент 4000.
db[collection_name].find( {'geometry.coordinates' : {'$geoWithin': { '$box' : [[lon1,lat1],[lon2,lat2]]}}}).limit(limit).toArray(function(err, rows)


Пока не доделал всё для постгри, просто решил выполнить запросы с одинаковыми параметрами без карты и вот что вышло:

  • MongoDB 6272 объекта за 42 сек.
db.points10m.find({
    "geometry.coordinates": { $geoWithin: { $box:
        [[85.71533203125, 57.89149735271031 ],
            [ 87.35620117187499, 61.05296842431332]]}}
}).count()

  • PostgreSQL/PostGIS 6247 объектов за 10,5 сек.
SELECT ST_AsGeoJSON(geom)
  FROM point1
  where ST_Within(geom,
  ST_GeomFromText('POLYGON(
  (57.89149735271031 85.71533203125,
  61.05296842431332 85.71533203125,
  61.05296842431332 87.35620117187499,
  57.89149735271031 87.35620117187499,
  57.89149735271031 85.71533203125))',
  4326));

Вот так, постгри в 4 раза быстрее на пространственной выборке.
Кто может помочь в исследовании милости просим!

Популярные сообщения из этого блога

Настройка сети в VirtualBox

/usr/bin/env: node: Нет такого файла или каталога

Использование WFS-источника Geoserver в своём сайте на Openlayers