Две коллекции mongodb в одном запросе

У меня есть большая коллекция клиентов и огромная коллекция данных клиентов, коллекции разделены, и я не хочу объединять их в одну коллекцию (из-за других уже работающих сервлетов), но теперь мне нужно "присоединиться" данные из обеих коллекций в один результат.

Поскольку запрос должен возвращать большое количество результатов, я не хочу один раз запрашивать сервер, а затем использовать результат для повторного запроса. Меня также беспокоит трафик между сервером и БД и память, которую результирующий набор будет занимать в оперативной памяти сервера.

Сейчас это работает так: я получаю соответствующий список клиентов из коллекции «клиенты» и отправляю этот список на запрос коллекции «данные клиента», и только тогда я получаю агрегированные результаты.

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

Как я могу использовать хранимую процедуру (функции javascript) для выполнения запроса в БД и возврата только соответствующих клиентов из коллекции. В качестве альтернативы, есть ли способ написать запрос, который объединяет результаты из другой коллекции?


person Toda Raba    schedule 15.02.2015    source источник
comment
нет таких опций для запроса нескольких коллекций в monogb. Одна вещь - использовать ReferenceField или ForienKey   -  person itzMEonTV    schedule 15.02.2015


Ответы (4)


«Хорошие новости для всех», этот запрос агрегации отлично работает в оболочке mongo как запрос на соединение.

db.clientData.aggregate([{
    $match: {
        id: {
            $in: db.clients.distinct("_id",
            {
                "tag": "qa"
            })
        }
    }
},
    $group: {
        _id: "$computerId",
        total_usage: {
            $sum: "$workingTime"
        }
    }
}]);
person Toda Raba    schedule 23.02.2015

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

Я не хочу объединять их в одну коллекцию

Это не хороший аргумент

Меня также беспокоит трафик между сервером и БД [...]

Если вам нужны данные, вам нужны данные. Как способ запроса имеет значение здесь?

[...] и память, которую результирующий набор будет занимать в оперативной памяти сервера.

Является ли объем данных настолько большим, что вы хотите передавать его с сервера на клиент таким образом, чтобы он передавался порциями? О каком объеме данных мы говорим, и почему клиент все это читает?

Как я могу использовать хранимую процедуру для выполнения запроса в БД и возврата только соответствующих клиентов из коллекции

В MongoDB нет хранимых процедур, но вы можете использовать карту на стороне сервера/reduce для "присоединения" коллекции. Как правило, код, хранящийся в базе данных и запускаемый ею, является нарушением разделения задач в многоуровневой архитектуре. Я считаю это одним из самых уродливых взломов всех времен, но это спорно.

Кроме того, менее спорно, имейте в виду, что M/R имеет огромные накладные расходы в MongoDB и не ориентирован на запросы в реальном времени, сделанные, например. в вызове веб-сервера. Эти вызовы займут сотни миллисекунд.

Есть ли способ написать запрос, который объединяет результат из другой коллекции?

Нет, операции ограничены одной коллекцией. Однако вы можете выполнить второй запрос и использовать там оператор $in, который похож на подвыборку и достаточно быстр, но, конечно, требует двух круговых обходов.

person mnemosyn    schedule 15.02.2015
comment
Большое спасибо за ваш добрый ответ. Я не хотел объединять их в одну коллекцию из-за других уже работающих сервлетов. Сейчас это работает следующим образом: я получаю соответствующий список клиентов из коллекции клиентов и отправляю этот список на запрос коллекции данных клиента, и только тогда я получаю агрегированные результаты. Да, мне нужны данные, но я хочу отключить получение и отправку списка клиентов с сервера и обратно на сервер, заставить сервер спрашивать себя, разрешить запрос сбора данных клиента, чтобы запросить сбор клиентов для соответствующего клиента. список. - person Toda Raba; 17.02.2015
comment
Под процедурами я подразумевал функции javascript - person Toda Raba; 17.02.2015

Как я могу использовать хранимую процедуру для выполнения запроса в БД и возврата только соответствующих клиентов из коллекции. Альтернативно

В MongoDB нет процедуры

В качестве альтернативы, есть ли способ написать запрос, который объединяет результаты из другой коллекции?

Обычно вам не нужно выполнять какие-либо соединения в MongoDB, и такой вещи нет. Гибкость документа справилась с уже типичными потребностями соединений. Вы должны подумать о своей модели документа, и вопрос о том, как спроектировать соединения из вашей схемы, всегда должен быть вашим первым портом захода. В качестве альтернативы вам может потребоваться использовать aggregation или Map-Reduce на стороне сервера, чтобы справиться с этим.

person styvane    schedule 15.02.2015
comment
Нет хранимой процедуры, подобной SQL, но есть способ хранить функции javascript, которые напоминают процедуры, я уверен, что ОП хочет знать об этом. docs.mongodb.org/manual/tutorial/ - person mshthn; 15.02.2015
comment
@LaszloTenki, вы правы, и, как я сказал в своем ответе, он может использовать Map-Reduce вместо этого на стороне сервера. - person styvane; 15.02.2015

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

Если у вас больше документов с данными клиента на одного клиента, то массив идентификаторов документов.

Но все это не избавляет вас от того, что вам придется реализовывать «присоединение» в коде вашего приложения, если это приложение Rails, то, вероятно, в вашем контроллере.

person mshthn    schedule 15.02.2015