LINUX.ORG.RU

Узнать сколько бутылок пива в магазине

 ,


0

2
Schema {
   shopName: String,
   beers: [{brand: String, vol: Number, alc: Number}]
}

model = new Schema();
model.findOne().countXXX



Нужно узнать сколько бутылок пива (countXXX) в магазинах, не вытаскивая все ящики

★★★★

Последнее исправление: gobot (всего исправлений: 1)

Не совсем понял что значит не вытаскивать все ящики. Тот же aggregate все равно читает этикетки на бутылках:

db.collection.aggregate([
  {
    $unwind: "$beers"
  },
  {
    $match: {
      "beers.brand": "Балтика9"
    }
  },
  {
    $group: {
      _id: null,
      count: {
        $sum: "$beers.count"
      }
    }
  }
])

Если под countXXX вы подразумеваете db.collection.countDocuments() то это буквально обертка, внутри которой тот же самый aggregate:

db.collection.aggregate([
   { $match: <query> },
   { $group: { _id: null, n: { $sum: 1 } } }
])
Obezyan
()

По простому никак.

Если очевидного индекса по магазу и/или бренду (+ запроса агрегатора) недостаточно, нужно делать свой materialized view и обновлять его периодически либо делать свой aggregate запрос c $merge. Можно навернуть дополнительный слой кеша, прямо в монге или соседнем редисе (ну мы же модную распределенную систему делаем, а чо). Но вообще монга старается кешировать результаты запросов, если они достаточно частые.

Если вопрос не из праздного любопытства, добавь больше информации: сколько данных, насколько большие группы, какой паттерн доступа к данным, и что ты вообще уже напрофилировал.

anonymous
()
Ответ на: комментарий от anonymous

Тут скорее стоит начать с вопроса «почему mongodb»? Такие данные просто идеальны для хранения в реляционной БД в третьей нормальной форме с индексацией и получением агрегированных данных с помощью реляционной алгебры. Одно удовольствие же с ними так работать, а не вот это вот все.

Obezyan
()
Ответ на: комментарий от Obezyan

У тебя должны быть очень веские причины, чтобы сегодня выбрать что-то отличное от постгреса. Этот дефолт легко отмасштабировать (если надо конечно) до огромных объемов и трафика. Встроенный json добавляет поддержку «документов».

Но, у ТС монга, и кто я такой, чтобы говорить ему все переделывать.

anonymous
()
Ответ на: комментарий от anonymous

Ну как то странно, срез можно сделать, вернуть частичный список

findOne().slice("beers", [0, 10])


А тупо подсчитать и вернуть количество нет? Мне данные если не нужны.

gobot ★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Отдельную сущность заводить и обновлять ее при каждом добавлении? Мне кажется должно быть просто и очевидно, сделал выборку документов, в каждом из них есть массив, почему нельзя вернуть просто его размер? Размер массива же где то в бинарном виде хранится, тупо счетчик 1 байт, его же не нужно считать, обходя все элементы через for. Просто не могу понять почему нет простого решения без aggregate. Slice есть, а size нет.

gobot ★★★★
() автор топика
Ответ на: комментарий от gobot

Так тебе вроде все комментаторы выше сказали что задача говно и проектировщик - мудак.

Там же и правда нужен постгрес + разработчик уровня 60к рублей в месяц. А ты там кстати чем занимаешься? Не оч понятно.

anonymous
()
Ответ на: комментарий от gobot

Отдельную сущность заводить и обновлять ее при каждом добавлении?

Да

Мне кажется должно быть просто и очевидно

Для нормальной базы да, но у тебя ж там монга.

ya-betmen ★★★★★
()
Ответ на: комментарий от gobot

Я как понимаю без этой уродливой конструкции с aggregate никак по другому?

Никак, это подход mongodb к получению агрегированных данных. А уродливо это все выглядит потому что для этих данных mongodb не очень подходит.

Мне то желательно документы получить в итоге

Причем тут документы? Вы написали «Нужно узнать сколько бутылок пива». Это число, а не коллекция документов где есть бутылки указанного бренда.

Obezyan
()
Ответ на: комментарий от gobot

Мне то желательно документы получить в итоге

Ну так и создай этот документ и считай бутылки в нем ручками. Вы хотели NoSQL, вы ее получили.

anonymous
()