Статьи

Как Санта использует MongoDB Часть 1: Использование геопространственных индексов для доставки подарков по всему миру

Мы любим смотреть, как все открывают свои подарки в рождественское утро, чтобы увидеть, что принес нам веселый старый Санта!

Задумывались ли вы, как Санта доставляет 6 миллиардов подарков за одну ночь? Как он собирает все эти письма «Дорогой Санта», читает их одну за другой, следит за тем, чтобы не было ошибок, пропущенных подарков и несогласованного состояния, чтобы какой-то бедный человек не получил два 3D-принтера daVinci 1.0, а их сосед по коридору не получает ничего? Как Санта узнает, сколько велосипедов взять? Сколько кукол? Сколько пожарных машин?

Доставка на Рождество — невероятная задача! Мы недавно обнаружили, что Санта использует MongoDB !!! Давайте внимательнее посмотрим.

Санта любит геопространственные индексы!

С более чем 6 миллиардами подарков, которые нужно доставить в 24 часовых пояса за одну ночь, это невероятное достижение, верно? Так как же Санта знает, как вовремя добраться до всех? И как он гарантирует, что каждый получает свою справедливую долю подарков от их списка пожеланий?

Санта хранит базу данных всех писем «дорогой Санта», которые попадают в его почтовый ящик (да, Санта знает, где ты живешь!), И у него много сумок, сгруппированных подарки по городу. В прошлом Санта использовал одну волшебную сумку для хранения всех подарков. Затем он прошел проверку в Финском агентстве по безопасности рабочей среды, и они рекомендовали распределить нагрузку по нескольким сумкам , как по состоянию здоровья (Санта не молодеет), так и по соображениям эффективности (что произойдет, если вы потеряете эту единственную сумку?!?).

Кроме того, Санта был вокруг квартала несколько раз, поэтому он знает, что монолитные подходы — вещь 90-х годов.

Санта ведет записи для каждого из нас, где он отслеживает, куда ему нужно доставить подарки. Он использует MongoDB (очевидно!) С геопространственной информацией, чтобы понять, куда доставить только что упакованные подарки. Каждая запись выглядит так:

{
    "_id": 123300410230,
    "name": "Norberto Leite",
    "location":{ 
        "geo": {
            "type": "Point",
            "coordinates": [ -8.611720204353333, 41.14341253682037]
                },
        "address" : {
            "country": "PT",
            "city": "Porto",
            "street": "Rua Escura 1",
            "zip": [4000, "Porto"],
        },
    },
}

Этот тип структуры данных позволяет Санте делать много разных вещей с помощью своего алгоритма распределения подарков.

Например, найти все подарки для доставки в Португалии:

> db.presents.find( { "location.address.country": "PT"  })

Но что на самом деле хочет знать Санта, какие подарки нужно доставить, как только он доберется до определенного города? Для решения этой проблемы Санта использует геопространственные возможности MongoDB .

Санта спросил его мастер Elf DBA , чтобы создать индекс 2dsphere таким образом , мы можем легко и эффективно сделать его поставки:

db.presents.ensureIndex( {"location.geo": "2dsphere"}  );

Очевидно, что, как и любой хороший и сертифицированный администратор базы данных MongoDB , чтобы избежать накладных расходов на работу с базой данных, мастер-эльф-администратор базы данных решил запустить создание индекса для вторичных серверов, не прерывая работу Санты. Никакое обновление статуса доставки подарка не должно ждать, пока создание этого индекса будет эффективно принято!

Затем Санта может доставить подарки в каждый дом в зависимости от расстояния до центра города. Чтобы получить приблизительное приближение на основе центроида города, Санта может использовать оператор {noformat} $ near {noformat}, чтобы получить список подарков, которые будут доставлены:

db.presents.find(  {"location.geo": { "$near": { "$geometry": {  "type": "Point", "coordinates": [-8.611720204353333, 41.14341253682037]  } }  } } )

Но Санта немного перфекционист, и чтобы получить более точное руководство по требованиям доставки, Санта использует карту многоугольника города Порту, в данном случае {}:

db.presents.find( {"location.geo" :{ "$geoWithin": {  "$geometry":{ "type": "Polygon", "coordinates": [
          [
            [
              -8.688468933105469,
              41.17400251011821
            ],
            [
              -8.642463684082031,
              41.18459702669797
            ],
            [
              -8.601951599121094,
              41.18459702669797
            ],
            [
              -8.582038879394531,
              41.169609159184255
            ],
            [
              -8.578948974609375,
              41.148413563966386
            ],
            [
              -8.594741821289062,
              41.14091592012965
            ],
            [
              -8.604354858398438,
              41.14453557935463
            ],
            [
              -8.614654541015625,
              41.1406573653974
            ],
            [
              -8.635597229003906,
              41.14815503879421
            ],
            [
              -8.667869567871094,
              41.148413563966386
            ],
            [
              -8.677825927734373,
              41.15022321163024
            ],
            [
              -8.688468933105469,
              41.17400251011821
            ]
          ]
        ] }  } }}  )

В следующем посте мы рассмотрим некоторые из техник, которые Санта использовал для повышения эффективности своего алгоритма доставки, переходя от одной магической сумки к нескольким сумкам. В конце концов, даже у Праздничного Духа есть углеродистая компенсация, и это не дешево.

Если вы хотите узнать больше о том, как Санта разработал свой рождественский план, загрузите руководство по архитектуре MongoDB здесь: