这个蒙古皮聚合命令有什么问题?

What's wrong with this mongoskin aggregation command?

本文关键字:命令 什么 问题      更新时间:2023-09-26

我有一个mongodb/mongoskin聚合请求如下:

db.collection(customerTable + '_earnedinfluencers').aggregate([
    {
        $group: {
            _id: '$user',
            name: '', // to be filled separately
            username: '', // to be filled separately 
            picture: '', // to be filled separately
            city: '', // to be filled separately
            kids: { $sum: '$kids' },
            revenue: { $sum: '$dayIncome' },
            kidsRevRatio: { $divide: [ { $sum: '$kids' }, { $sum: '$dayIncome' } ] }
        }, 
        $match: {
            richness: { $gte: variable1 },
            kids: { $lt: variable2 },
            hobbies: { $in: ['hobby1', 'hobby2', 'hobby3', 'hobby4'] },
            event: { $in: schoolfestival },
            event: { $ne: 0 }
        },
        $project: {
            _id: 0,
            user: '$_id',
            name: 1,
            username: 1,
            picture: 1,
            city: 1,
            kids: 1,
            revenue: 1,
            kidsRevRatio: 1
        }
    }
], function(err, result) {
    // do something with err and result
});

上面的代码给出了以下错误:

Error: {"name":"MongoError","errmsg":"exception: A pipeline stage specification object must contain exactly one field.","code":16435,"ok":0}

我不熟悉mongo和db,不知道我做错了什么

您的管道参数是不平衡的,每个阶段都是一个单独的文档,所以您需要包装每个阶段。但也有一些其他的问题

db.collection(customerTable + '_earnedinfluencers').aggregate([
    { $match: {
            richness: { $gte: variable1 },
            kids: { $lt: variable2 },
            hobbies: { $in: ['hobby1', 'hobby2', 'hobby3', 'hobby4'] },
            event: { $in: schoolfestival },
    }},
    { $group: {
            _id: '$user',
            name: { '$first': '$name' },
            username: { '$first': '$username' },
            picture: { '$first': '$picture' },
            city: { '$first': '$city' }
            kids: { '$sum': '$kids' },
            revenue: { '$sum': '$dayIncome' },
            kidsSum: { '$sum': '$kids' },
    }}, 

    { $project: {
            _id: 0,
            user: '$_id',
            name: 1,
            username: 1,
            picture: 1,
            city: 1,
            revenue: 1,
            kidsSum: 1,
            kidsRevRatio: { $divide: [ '$kidsSum', '$revenue' ] }
    }}
], function(err, result) {
    // do something with err and result
});

您将整个管道作为一个文档,它实际上需要一个文档数组,如所示。

但是你真的想要 $match 首先来过滤你的结果。如果你真的想在组之后做一些额外的匹配,那么你可以在之后的管道中添加一个额外的匹配。

$group 操作要求_id分组键之外的所有字段都需要有一个"分组操作符",您不能自己获得字段,除非它们是您分组的_id的一部分。通常,您需要一个操作符,如 $first ,否则将它们完全省略。

仅是顶级分组操作符,因此像 $divide 这样的操作不是分组操作符。为了在处理一个或多个 $sum 结果时执行此操作,您可以使用具有计算值的字段将其移动到后面的 $project

同样像project和group这样的操作,从管道中"移除"字段,只保留那些你特别包含的字段。因此,您不能指定不存在的字段。这就是为什么$match出现在前面的原因之一,也是您可以使用索引的地方,并且只能在管道的开始处这样做。

但是对于每个阶段,唯一存在的字段将是那些提到的字段。作为进一步的优化,"优化器"将从一开始就不包括文档中没有特别提到的任何字段。因此,只有那些在第一场比赛和小组赛阶段被引用的人将被包括在其余的管道阶段,然后可能再次被过滤掉。