Эксперименты с 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)
Пока не доделал всё для постгри, просто решил выполнить запросы с одинаковыми параметрами без карты и вот что вышло:
"geometry.coordinates": { $geoWithin: { $box:
[[85.71533203125, 57.89149735271031 ],
[ 87.35620117187499, 61.05296842431332]]}}
}).count()
db[collection_name].find( {'geometry.coordinates' : {'$geoWithin': { '$box' : [[lon1,lat1],[lon2,lat2]]}}}).limit(limit).toArray(function(err, rows)
Пока не доделал всё для постгри, просто решил выполнить запросы с одинаковыми параметрами без карты и вот что вышло:
- MongoDB 6272 объекта за 42 сек.
"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));
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 раза быстрее на пространственной выборке.
Кто может помочь в исследовании милости просим!
Комментарии
Отправить комментарий