如何在Waterline或MongoDB中进行选择、分组和连接操作

11

我有三个模型: user, noun, 和 usernoun(在PHP/Eloquent中为user_noun)。usernoun 之间有一个多对多的关系。 "pivot" 表格有一个额外的属性 score。 我可以使用 Eloquent 查询来计算每个用户所获得的分数总和,其中包括他们拥有的每个名词的分数:

$users = User::leftJoin('noun_user', 'user.id', 'noun_user.user_id')
    ->groupBy('user.id')
    ->select('user.*', DB::raw('sum(noun_user.score) as score'))
    ->orderBy('score', 'desc')
    ->get();

但是我不知道该怎么让它在Waterline中工作。这段代码本来可以运行,但当我取消注释.populate('user')时就不能正常工作了。我需要user被填充。

UserNoun
    .find({})
    //.populate('user')
    .groupBy('user')
    .sum('score')
    .sort({ score: 'desc' })
    .exec((err, usernouns) => {
    return res.json(usernouns)
})

这里有一个可以正常工作的 .native() 查询:

UserNoun.native(function(err, collection) {
    collection.aggregate([
        {
            $lookup: {
                from: 'user',
                localField: 'user',
                foreignField: '_id',
                as: 'user'
            }
        },
        {
            $group: { _id: '$user', total: { $sum: '$score' } }
        },
        {
            $sort : { total: -1 }
        }
    ]).toArray(function (err, results) {
        return res.json(results)
    })
})

这个原生查询能否使用groupBypopulatesum在Waterline中进行重写?

2个回答

6
截至Waterline@0.11.8版本,唯一的方法就是使用本地查询。
顺便提一下,您可以在用户模型中导出您的方法:
// User.js
module.exports = {

    // ...

    findTotalScores: function (callback) {
        UserNoun.native(function(err, collection) {
            if (err) {
                return callback(err);
            }

            collection.aggregate([
                {
                    $lookup: {
                        from: 'user',
                        localField: 'user',
                        foreignField: '_id',
                        as: 'user'
                    }
                },
                {
                    $group: { _id: '$user', total: { $sum: '$score' } }
                },
                {
                    $sort : { total: -1 }
                }
            ]).toArray(callback);
        });
    }

};

你可以通过调用以下方法在你的控制器中使用它:

User.findTotalScores(function (err, results) {
    return res.json(results);
});

0

目前无法使用Waterline进行连接操作,您必须使用原始查询。populate只会填充关联字段,它不会像SQL join一样返回结果。

目前Waterline仅支持与sum()、count()等组合使用groupBy。

对于groupBy和sort,您可以使用以下内容:

Model.find()  
.groupBy('term') 
.sum('count')  
.limit(20)
.sort({count: 'desc'}) 
.exec(function (err, data){
//Your code here..
});

请问您能否分享groupBysum方法的参考链接? - Sangharsh
无法找到确切的文档,但我尝试了在Sails中使用groupby查询和计算函数。找到一个链接 - https://dev59.com/_3nZa4cB1Zd3GeqPsqWe - Sapna Jindal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接