MongoDB находит повторяющиеся значения в массиве

Скажем, у меня есть коллекция с такими документами, как…

{
    'name': 'Hawaiian',
    'toppings': ['ham', 'cheese', 'pineapple'],
}

Or—

{
    'name': 'Peperonni',
    'toppings': ['cheese', 'pepperoni'],
}

Как я могу получить список всех topping, которые появляются более чем в одном документе? Таким образом, для двух документов выше это будет cheese.

В идеале, как можно «ближе» к базе данных — я знаю, что могу получить список всех начинок с помощью distinct, а затем пройтись по всем документам на уровне приложения, но это было бы слишком дорого.

Спасибо!


person user1569050    schedule 05.11.2012    source источник


Ответы (2)


Хоть и длинный запрос, но посмотреть можно. Это структура агрегации с mongodb 2.2.

db.test2.aggregate({$project:{"toppings":1, "_id":0}}, {$unwind:"$toppings"}, {$group:{"_id":"$toppings", count:{$sum:1}}}, {$match:{count:{$gt:1}}}, {$project:{"_id":1}})

{ "result" : [ { "_id" : "cheese" } ], "ok" : 1 }

Объясните шаг моего запроса:

  1. Нужно только поле toppings
  2. Развернуть все значения в toppings
  3. Сгруппируйте по значениям в toppings и подсчитайте количество
  4. Найдите число значения, которое больше 1
  5. Получить только значение(начинки), count не нужно.
person Chien-Wei Huang    schedule 05.11.2012

Я бы получил список всех начинок, а затем проверил

db.coll.find({"topping": topping}).count() > 1

Обратите внимание, что я пробовал это в оболочке mongo, и хотя синтаксис pymongo был бы точно таким же, я не уверен, где реализован подсчет - в pymongo или в базе данных.

[РЕДАКТИРОВАТЬ]

pymongo, похоже, делегирует count() в mongodb, так что вместо полного запроса операция подсчета выполняется базой данных.

person yati sagade    schedule 05.11.2012
comment
Я предполагаю, что это внутри цикла, перебирающего все toppings — в моем случае список пицц и начинок смехотворно длинный — для вычисления требуется слишком много времени. Я надеялся, что это можно сделать в БД (возможно, MapReduce?) - person user1569050; 05.11.2012
comment
о, тогда перейдите к структуре агрегации. Там опубликован один ответ - я много слышал о его эффективности, но никогда не пробовал серьезно :) - person yati sagade; 05.11.2012