Я новичок в MongoDB. Я пишу приложение, используя мон goose и NodeJS. Я начинаю с этой коллекции:
[
{ name: "Joe", hobby: "Food"},
{ name: "Lyn", hobby: "Food"},
{ name: "Rex", hobby: "Play"},
{ name: "Rex", hobby: "Shop"},
...
]
И я хочу вывести подмножество документов с двумя новыми полями: nameCount
, показывающее, сколько раз появляется значение имени документа, и hobbyCount
, показывающее то же самое вещь для хобби документа:
[
{ name: "Joe", hobby: "Food", nameCount: 1, hobbyCount: 2 },
{ name: "Lyn", hobby: "Food", nameCount: 1, hobbyCount: 2 },
{ name: "Rex", hobby: "Play", nameCount: 2, hobbyCount: 1 },
{ name: "Rex", hobby: "Shop", nameCount: 2, hobbyCount: 1 }
]
Из моих исследований и размышлений я получил следующий запрос для работы, но он кажется чрезмерным, неэффективным и чрезмерно сложным.
db.members.aggregate([
{$skip: 0},
{$limit: 4},
{
$lookup: {
from: "members",
let: { name: "$name"},
pipeline: [
{ $match: { $expr: { $eq: ["$name", "$$name"] } } },
{ $count: "count" }
],
as: "nameCount"
}
},
{ $unwind: "$nameCount" },
{ $addFields: { nameCount: "$nameCount.count" } },
{
$lookup: {
from: "members",
let: { hobby: "$hobby"},
pipeline: [
{ $match: { $expr: { $eq: ["$hobby", "$$hobby"] } } },
{ $count: "count" }
],
as: "hobbyCount"
}
},
{ $unwind: "$hobbyCount" },
{ $addFields: { hobbyCount: "$hobbyCount.count" } }
]);
Пн go Детская площадка
Меня, в частности, беспокоит не только то, что запрос кажется чрезмерным, но и то, что я выполняю два новых поиска в запись, найденная во всей коллекции, когда, возможно, nameCount
и hobbyCount
могут быть скомпилированы в одном поиске.
Обновление
Валиджон опубликовал ответ, который заставил меня понять, что я упростил свой фактический проблема при попытке выложить минимум необходимого. На самом деле коллекция фильтруется (с помощью $ match, $ skip и $ take) перед первым поиском, который я опубликовал. В результате ответ Валижона на самом деле не работает для меня, хотя это отличный ответ на то, как я изначально поставил проблему. Извините, я обновляю OP
Смотрите игровую площадку