我是MongoDB的新手。我正在用猫鼬和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" } }
]);
它尤其困扰着我,不仅是查询看起来有点过火,而且看起来我正在运行整个集合中找到的每条记录的两个新搜索,而也许可以在一个搜索中编译nameCount
和hobbyCount
。
更新
Valijon发布了一个答案,这让我意识到,当我试图发布最低要求时,我过于简化了我的实际问题。实际上,在我发布的第一次查找之前对集合进行了筛选(使用$match、$skip和$take)。因此,Valijon的回答实际上对我无效,尽管它是我最初提出问题的方式的一个很好的答案。抱歉,我在更新OP
发布于 2020-01-18 15:30:25
编辑:我们只需要使用一个$lookup
(我们的名字和爱好都匹配),并通过应用$filter
或$reduce
运算符来计数nameCount
和hobbyCount
db.members.aggregate([
{
$skip: 1
},
{
$limit: 2
},
{
$lookup: {
from: "members",
let: {
name: "$name",
hobby: "$hobby"
},
pipeline: [
{
$match: {
$expr: {
$or: [
{
$eq: [
"$name",
"$$name"
]
},
{
$eq: [
"$hobby",
"$$hobby"
]
}
]
}
}
}
],
as: "count"
}
},
{
$project: {
_id: 0,
name: 1,
hobby: 1,
nameCount: {
$reduce: {
input: "$count",
initialValue: 0,
in: {
$add: [
"$$value",
{
$cond: [
{
$eq: [
"$name",
"$$this.name"
]
},
1,
0
]
}
]
}
}
},
hobbyCount: {
$size: {
$filter: {
input: "$count",
cond: {
$eq: [
"$hobby",
"$$this.hobby"
]
}
}
}
}
}
}
])
https://stackoverflow.com/questions/59804565
复制