这个mongoskin聚合命令有什么问题?

jee*_*ace 3 javascript mongodb node.js mongoskin aggregation-framework

我有一个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
});
Run Code Online (Sandbox Code Playgroud)

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

Error: {"name":"MongoError","errmsg":"exception: A pipeline stage specification object must contain exactly one field.","code":16435,"ok":0}
Run Code Online (Sandbox Code Playgroud)

我一般都是mongo和db的新手,并且不知道我做错了什么.

Nei*_*unn 11

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

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
});
Run Code Online (Sandbox Code Playgroud)

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

但实际上你想要$match先过滤你的结果.如果你真的想在一个组之后进行一些额外的匹配,那么之后你会在管道中添加一个额外的匹配.

$group操作要求_id分组键之外的所有字段都需要具有"分组操作符",除非它们属于_id您的组,否则您不能仅通过它们自己返回字段.通常,您需要一个运算符,例如$first或完全省略它们.

仅限顶级分组运算符,因此类似$divide的操作不是分组运算符.为了在处理一个或多个$sum结果时执行此类操作,请$project使用包含计算值的字段将其移至稍后.

此外,诸如项目和组之类的操作会从管道中"删除"字段,并仅保留您专门包含的字段.因此,您无法指定不存在的字段.这就是为什么它$match是第一个以及你可以使用索引的原因之一,并且只有在管道的开始才能完成.

但是对于每个阶段,唯一存在的领域将是那些提到的领域.作为进一步优化,"优化器"将从一开始就不包括文档中存在的任何未明确提及的字段.因此,只有在第一个匹配和组合阶段中引用的那些将被包括在其余的pipline阶段中,然后可能再次被过滤掉.