【问题标题】:How to select, groupBy, and join in Waterline or MongoDB如何在 Waterline 或 MongoDB 中选择、分组和加入
【发布时间】:2017-06-17 04:22:42
【问题描述】:

我有三个模型:usernounusernoun(在 PHP/Eloquent 中为user_noun)。 usernoun 之间存在多对多关系。 “数据透视”表有一个额外的属性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 中重写吗?

【问题讨论】:

    标签: php mongodb eloquent sails.js waterline


    【解决方案1】:

    到目前为止,您不能使用水线进行连接,您必须为此使用原始查询。 populate 只会填充关联的字段,它不会像 sql join 返回结果那样返回结果。

    此时的Waterline仅支持组合使用groupBy 使用 sum()、count() 等。

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

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

    【讨论】:

    • 能否分享groupBysum 方法的参考链接?
    • 无法找到确切的文档,但我尝试了查询,sails 中的 groupby 使用计算函数。找到一个链接 - stackoverflow.com/questions/20254910/…
    【解决方案2】:

    从 Waterline@0.11.8 开始,唯一的方法是使用本机查询。

    顺便说一句,你可以在 User 模型中导出你的方法:

    // 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);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      相关资源
      最近更新 更多