LINUX.ORG.RU

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

 ,


0

1
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

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

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

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

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

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

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

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

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

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

К каждому документу цеплять поле countBottle... хотя... я начинаю понимать в чем причина, в некотором дизайне, либо документ получай, либо произвольные данные aggregate,а микшировать никак нет

уродливо это все выглядит потому что для этих данных mongodb не очень подходит

ойй да ладно, подходит не подходит

*** MongoDB подходит для следующих применений: ***

регистрация и хранение информации о событиях;
системы управления документами и контентом;
электронная коммерция;
игры;
данные мониторинга, датчиков;
мобильные приложения;
хранилище операционных данных веб-страниц (например, хранение комментариев, рейтингов, профилей пользователей, сеансы пользователей)

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

Просто select count

просто? Из 2 таблиц данные же будут. select *, (select count from beers where show_id = s_id) as countB from shops

А в монго в 1 документе. Проблем по сути нет, если вытащить все эти бутылки и локально подсчитать array.length, но зачем мне их вытаскивать, если я с этими данными работать сейчас не буду. Собственно мне нужно сделать проверку перед добавлением бутылки в магазин. Если бутылок больше 10, то выгнать поставщика, ибо нет места в магазине.

Просто я не пойму почему бл такое через aggregate только делается! Западло мне так делать. Хочу в документ добавить «инородное поле»

ЗЫ. Есть там $push {$slice}... Но это truncate, старые бутылки будут потеряны, но магаз не переполнится... Но хочется проверку хотя бы перез $push

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

Ладно я спать, завтра продолжим. Пишите пока все решения, которые мне подойдут по проверке бутылок перед добавлением. Если > 10, то не добавлять и дать пинка поставщику который их принес. НО, не вытаскивая все бутылки. $push {$slice} не предлагать

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

Просто я не пойму почему бл такое через aggregate только делается! Западло мне так делать. Хочу в документ добавить «инородное поле»

Так aggregate это база. Запросов в mongoDB, куча функций буквально обертки над ним.

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

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

Так aggregate это база

Хорошо. Учту

используете не правильный инструмент для задачи

А ты что задачу знаешь что-ли? Чем задача с магазином не годна для монги, объясни? Мне кажется это самое примитивный пример, такими все форумы завалены - это стандартная схема - документ - в нем массивы. Что, все дураки, используют монгу не правильно или че?

воротите нос

о боже, где я ворочу нос? Я тебе чем-то обязан?

Вы эникейщик самого низкого пошиба, фу таким быть

О боже, ну хорошо, считай что ты меня унизил и самоутвердился. Ты крутой! Ты бох и гуру вселенного масштаба!

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

Ну епта, есть таблица магазов, есть таблица бутылок. Бутылки прикреплены к магазу. Это в sql. В монге один документ - магаз - в нем массив бутылок. Поэтому вместо 2 запросов в sql, в монге делается один и в нем все вложенности. Это же очевидно. Пример привел специально мега примитивный и стандартный - ну банальней такого ничего нет

У тебя селект по таблице с пивом

Да нет же, отдельно пиво никто искать не будет, сначала ищут магаз, потом смотрят ассортимент в нем, ну можно фильтр сделать по названию, да, бренду, но уже в контексте магазина, но это не селект, локально фильтр array.filter() ну либо запросом можно через $elemMatch {«beens.brans»: «Очаково»} сразу вытянуть нужные бутылки вместе с магазом

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

Поэтому вместо 2 запросов в sql, в монге делается один и в нем все вложенности. Это же очевидно.
...
сначала ищут магаз, потом смотрят ассортимент в нем

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

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

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

значит на момент поиска пива


Я не ищу пиво епта.
Поиск вообще не нужен, просто каталог, выгребаешь по ид магаз и нужно узнать сколько пива в нем, не вытаскивая все бутылки

gobot ★★★★
() автор топика

в цклом кури доки монги

ты в монгу не фейхуа и доказываешь что бы тебе доказывали что бы ты не фейхуа в пострескуль

а на фейхуа это ооастальным?!

чисто для

https://people.csail.mit.edu/tdanford/6830papers/

http://db.lcs.mit.edu/6.5830/

qulinxao3 ★★
()
Последнее исправление: qulinxao3 (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

Мне нужно и магазин получить и бутылки в нем сразу. В монге это 1 запросом делается, в sql двумя. Кому нужны бутылки без адреса магазина? Ладно, это уже интересно, тема в другом совсем...

gobot ★★★★
() автор топика