Статьи

Географическая индексация MongoDB позволяет использовать коллекцию в качестве карты

 

Геопространственная индексация MongoDB позволяет использовать коллекцию в качестве карты. Он работает не так, как «нормальное» индексирование, но на самом деле есть хороший визуальный способ увидеть, что делает геопространственное индексирование.

Допустим, у нас есть карта 16 × 16; что-то похожее на это:

Все координаты на нашей карте (как описано выше) находятся где-то между [0,0] и [16,16], поэтому я собираюсь установить минимальное значение 0 и максимальное значение 16.

db.map.ensureIndex({point : "2d"}, {min : 0, max : 16, bits : 4})

 

Это по сути превращает нашу коллекцию в карту. (Не беспокойтесь о битах , сейчас я объясню это ниже.)

Допустим, у нас есть что-то в точке [4,6]. MongoDB генерирует геохэш этой точки, который описывает точку таким образом, чтобы упростить поиск объектов рядом с ней (и при этом иметь возможность распределять карту по нескольким серверам). Геохеш для этой точки представляет собой цепочку битов, описывающую положение [4,6]. Мы можем найти геохэш этой точки, разделив нашу карту на квадранты и определив, в каком квадранте она находится. Итак, сначала мы разделим карту на 4 части:

Это самая сложная часть: каждый квадрант может быть описан двумя битами, как показано в таблице ниже:

01 11
00 10

[4,6] находится в нижнем левом квадранте, что соответствует 00 в таблице выше. Таким образом, его геохэш начинается с 00.

Пока геохаш: 00

Теперь мы снова разделим этот сектор:

 

[4,6] теперь находится в верхнем правом квадранте, поэтому следующие два бита в геохэше равны 11. Обратите внимание, что нижний и левый края включены в квадрант, верхний и правый края исключены.

Пока геохаш: 0011

Теперь мы снова разделим этот сектор:

[4,6] теперь находится в верхнем левом квадранте, поэтому следующие два бита в геохеше — 01.

Пока геохаш: 001101

Теперь мы снова разделим этот сектор:

[4,6] теперь находится в нижнем левом квадранте, поэтому следующие два бита в геохеше — 00.

Пока что геохаш: 00110100

Вы можете задаться вопросом: как далеко мы продолжаем делиться? Это именно то, для чего предназначена установка битов . Мы установили его на 4 при создании индекса, поэтому мы делим на квадранты 4 раза. Если бы мы хотели более высокую точность, мы могли бы установить биты на что-то более высокое.

Вы можете проверить свою математику выше, используя команду geoNear , которая возвращает геохэш для точки, возле которой вы ищете:

> db.runCommand({geoNear : "map", near : [4,6]})
{
	"ns" : "test.map",
	"near" : "00110100",
	"results" : [ ],
	"stats" : {
		"time" : 0,
		"btreelocs" : 0,
		"nscanned" : 0,
		"objectsLoaded" : 0,
		"avgDistance" : NaN,
		"maxDistance" : -1
	},
	"ok" : 1
}

 

Как видите, поле «ближний» содержит именно тот геохэш, который мы ожидаем из наших расчетов.

Интересная вещь о геохэшинге состоит в том, что это позволяет легко определить, что находится рядом с нами, потому что вещи отсортированы в соответствии с их положением на карте: каждый документ с точкой геохеша, начинающейся с 00, находится в нижнем левом квадранте, каждая точка начинается с 00111111 очень близко к середине, но в левом нижнем квадранте. Таким образом, вы можете посмотреть, где находится точка, посмотрев на ее геохэш.

Биты и точность

Допустим, волшебник накладывает огненное кольцо вокруг себя с радиусом 2. Захвачена ли точка [4,6] в этом огненном кольце?

Из рисунка видно, что это не так, но если мы посмотрим на геохэш, мы на самом деле не можем сказать: [4,6] хеширует до 00110100, но то же самое делает [4.9, 6.9] и любое другое значение в квадрат между [4,6] и [5,7]. Таким образом, чтобы выяснить, находится ли точка внутри круга, MongoDB должен перейти к документу и посмотреть фактическое значение в поле точки . Таким образом, установка битов в 4 немного низка для данных, которые мы используем / запросы, которые мы делаем.

Как правило, вам не стоит беспокоиться об установке битов , я установил их выше только для демонстрации. биты по умолчанию равны 26, что дает разрешение приблизительно 1 фут с использованием широты и долготы. Чем больше число битов, тем медленнее получается геохэш (наоборот, чем меньше бит, тем быстрее геохэш, но больше доступа к документам при поиске). Если вы выполняете запросы с высоким или низким разрешением, вы можете поиграть с разными значениями битов (в dev, в репрезентативном наборе данных) и посмотреть, получите ли вы лучшую производительность.

Спасибо Грегу Штудеру , который в прошлую пятницу выступил с докладом о геопространственных технологиях и вдохновил этот пост. (Каждую пятницу инженер 10gen проводит технический разговор о том, над чем они работают, и это действительно хороший способ не отставать от всего того, что делают коллеги. Если вы когда-либо управляете техническим отделом, я очень рекомендую их!)

 Источник: http://www.snailinaturtleneck.com/blog/2011/06/08/mongo-in-flatland/