如何在Mongodb中使用聚合在响应的输出上创建数组
我的收藏中有一个具有以下结构的对象列表:如何在Mongodb中使用聚合在响应的输出上创建数组,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我的收藏中有一个具有以下结构的对象列表: [ { "country": "colombia", "city":"medellin", "calification": [ { "_id": 1, "stars": 5 }, { "_id": 2, "stars": 3 } ] }, { "count
[
{
"country": "colombia",
"city":"medellin",
"calification": [
{
"_id": 1,
"stars": 5
},
{
"_id": 2,
"stars": 3
}
]
},
{
"country": "colombia",
"city":"manizales",
"calification": [
{
"_id": 1,
"stars": 5
},
{
"_id": 2,
"stars": 5
}
]
},
{
"country": "argentina",
"city":"buenos aires",
"calification": [
{
"_id": 1,
"stars": 5
},
]
},
{
"country": "perú",
"city":"cusco",
"calification": [
{
"_id": 3,
"stars": 3
},
]
}
]
我正在尝试制作一个过滤器,以便输出每个国家的数组数量。这就是我想要的输出示例
avg
将是结果sum
'stars'/calification.length
{
"colombia": [
{
"city": "medellin",
"avg": 4,
"calification": [
{
"_id": 1,
"stars": 5
},
{
"_id": 2,
"stars": 3
}
]
},
{
"city": "manizales",
"avg": 5,
"calification": [
{
"_id": 1,
"stars": 5
},
{
"_id": 2,
"stars": 3
}
]
}
],
"argentina": {
"city": "buenos aires",
"avg": 5,
"calification": [
{
"_id": 1,
"stars": 5
}
]
},
"peru": {
"city": "cusco",
"avg": 4,
"calification": [
{
"_id": 1,
"stars": 4
}
]
}
}
我正在尝试这样做:
Alcalde.aggregate([
{
$addFields: {
colombia: {
"$push": {
"$cond": [{ $eq: ["$country", "'Colombia'"] }, true, null]
}
}
}
},
{
$project: { colombia: "$colombia" }
}
]
我该怎么做呢我们可以让它更优雅 MongoDB有操作符,让我们使用它。此外,我们还可以使用
$group
操作符对同一国家的城市进行分组
最后,应用+**转换为期望的结果
**这是因为我们不能使用这样的表达:{“$country”:“$city”}
试试这个:
Alcalde.aggregate([
{
$group: {
_id: "$country",
city: {
$push: {
"city": "$city",
"avg": { $avg: "$calification.stars"},
"calification": "$calification"
}
}
}
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: [ [{ "k": "$_id", "v": "$city"}] ]
}
}
}
])
编辑:填充城市
内部对象的通用方法
$$ROOT
是存储根文档的变量
$mergeObjects
向最终对象添加/覆盖字段
Alcalde.aggregate([
{
$group: {
_id: "$country",
city: {
$push: {
$mergeObjects: [
"$$ROOT",
{
"avg": { "$avg": "$calification.stars" }
}
]
}
}
}
},
{
$project: {
"city.country": 0
}
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: [
[ { "k": "$_id", "v": "$city" } ]
]
}
}
}
])
非常感谢!我多么希望达到你的水平。我还有最后一个问题,您手动包括“city”:“$city”,“calification”:“$calification”
,是否有方法导入其余的集合字段而不手动声明它们?(在我的真实示例中,我有许多其他字段)@yavg再次检查,我添加了通用方法。练习,练习,再练习:-)我很感激,这让我对你有些羞愧。我有一个问题。只有在哥伦比亚的情况下才可以过滤,只返回麦德林市的信息吗?@yavg-Sure。检查一下,非常感谢,但它不起作用。它显示了哥伦比亚的另一个城市“马尼萨雷斯”。它不再显示其他国家及其城市。我想要的是,在哥伦比亚的例子中,它只显示了“麦德林”这个城市
Alcalde.aggregate([
{
$group: {
_id: "$country",
city: {
$push: {
$mergeObjects: [
"$$ROOT",
{
"avg": { "$avg": "$calification.stars" }
}
]
}
}
}
},
{
$project: {
"city.country": 0
}
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: [
[ { "k": "$_id", "v": "$city" } ]
]
}
}
}
])