Mysql в MongoDB и запрос, эквивалентный этой схеме

У меня есть сложная база данных местоположений со следующей схемой:

table States
id : INT PK AutoIncrement
name : VarChar 50 UNIQUE

table Counties 
id: INT PK AutoIncrement
stateID : INT ForeignKey ->States(id)
name : VARCHAR(50)

table Towns : 
id: INT PK AutoIncrement
stateID : INT ForeignKey ->States(id)
countyID : INT ForeignKey ->Counties(id)
name : VARCHAR(50)

table listings
id : INT PK autoincrement
name: varchar(50)
stateID: INT
countyID:  INT
townID:  INT

Когда я хочу отобразить некоторые статистические данные о географическом перераспределении в виде дерева, например:

  • state1 (105 results)
    • county 1 (50 results)
    • county 2 (55 results)
      • Town 1 ( 20 results)_
      • Город 2 ( 35 результатов)
  • state2 (200 результатов) ect...

В mySQL я бы сделал такие запросы:

**1-й уровень: **

 select count(*) as nb, S.namem, S.id as stateID from listings L INNER JOIN States S ON S.id=L.stateID GROUP BY S.id;

**2-й уровень: **

 foreach(results as $result){
      $sql = "select count(*) as nb, from listings L INNER JOIN Counties C ON C.id=L.countyID WHERE L.stateID=".$result['stateID'];
 });

и так далее... В MySQL тоже есть способ сделать это в уникальном длинном запросе.

Это тривиальный запрос, и он очень быстро выполняется на SSD-диске в Mysql.

Я начинаю изучать mongoDB и хочу знать, какую схему мне следует использовать для хранения данных о моем местоположении, чтобы оптимизировать операции $count() и $group().

И какой запрос монго выполнит эту работу?


person Ant    schedule 25.09.2014    source источник


Ответы (1)


Храните документы со структурой, подобной таблице listings:

{
    "name" : "listing0",
    "state" : "Maryland",
    "county" : "Washington",
    "town" : "Faketown"
}

Затем просто найдите тройное количество списков на (штат, страну, город) с конвейером агрегации.

> db.listings.aggregate([
    // hopefully an initial match stage to select a subset of search results or something
    { "$group" : { "_id" : { "state" : "$state", "county" : "$county", "town" : "$town" }, "count" : { "$sum" : 1 } } }
])

Отсюда вы можете вычислить числа для более высокого уровня дерева, перебирая курсор результата, или вы можете запустить аналогичные конвейеры для вычисления чисел на более высоком уровне дерева. Например, для номеров округов в конкретном штате

> db.listings.aggregate([
    // hopefully an initial match stage to select a subset of search results or something
    { "$match" : { "state" : "Oregon" } },
    { "$group" : { "_id" : { "state" : "$state", "county" : "$county" }, "count" : { "$sum" : 1 } } }
])
person wdberkeley    schedule 25.09.2014
comment
Хорошо ~ Просто для подтверждения. Если у меня есть список из 10 состояний, и я хочу отобразить дерево со счетом для каждого состояния, с развернутым деревом одного состояния, мне придется сделать 2 запроса. Один для получения количества/группы по штатам, а другой для развернутого дерева, сгруппированного по округам. Я бы также использовал целое число для подсчета/группировки данных, так как это быстрее, чем сопоставление текста. - person Ant; 26.09.2014
comment
Зависит от метода/объема клиентской обработки. Вы можете получить все более высокие уровни дерева из одного запроса, чтобы получить подсчет на самом низком уровне, если вы выполняете сканирование на стороне клиента и суммируете результаты. - person wdberkeley; 26.09.2014