Как выбрать, сгруппировать и присоединиться к Waterline или MongoDB

У меня есть три модели: user, noun, а также usernoun (user_noun в PHP / Eloquent). Между многими существует связь user а также noun, В сводной таблице есть дополнительный атрибут 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();

Но я не могу понять, как заставить это работать в Ватерлинии. Это работает, но не когда я раскомментирую .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)
})
})

Можно ли переписать этот собственный запрос в Waterline с помощью groupBy а также populate а также sum?

11

Решение

Начиная с [email protected], единственный способ сделать это — использовать собственные запросы.

Кстати, вы можете экспортировать свой метод внутри модели 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);
});
6

Другие решения

Вы не можете делать соединения с ватерлинией на данный момент, вам придется использовать необработанные запросы для этого. populate заполняет только связанные поля, но не возвращает результат, как SQL-соединение возвращает его.

Водная линия на данный момент поддерживает только использование groupBy в комбинации
с sum (), count () и т. д.

Для групповой и сортировки вы можете использовать следующее:

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

По вопросам рекламы [email protected]