2014-12-18 3 views
0

у меня есть проблемы с sailsJs я хочу, чтобы выбрать все с подсчетом сообщений, групп + кол-сообщений, которые принадлежат к текущей группе, моего кода, как этотПроблемы с выбором на парусахJs?

Group.find().exec(function (err, groups) { 
    if (err) 
     return next(err); 
    _.each(groups, function (grouper) { 
     Messages.find({ 
      groupId : grouper.id, 
     }).exec(function (err, somethingfunctions) { 
      console.log(groups), 
      console.log(somethingfunctions.length), 
     }); 
    }); 
}); 

я хочу somethink как этот

имя группы + количество сообщений, относящихся к текущей группе; , например

webdevelopment - 34 messages 

я не могу понять, как сделать это с sailsJs

+0

Я думаю, в ответе ниже рассматривается один аспект проблемы (подсчет сообщений). Остается одно: выполнение нескольких 'Messages.find()' или 'Messages.count()' внутри цикла '_.each()' подразумевает, что вы должны каким-то образом получить результаты обратных вызовов * all * запросов. Таким образом, у вас должен быть механизм синхронизации, поэтому перед отправкой ответа вы получите все результаты обратных вызовов. Я попытаюсь найти пример того, как вы можете это сделать, с библиотекой, такой как [async] (https://github.com/caolan/async). – Benito

ответ

0

Используйте count метод предназначен для models внутри _.each(groups, function (grouper), например, так:

Messages 
.count({groupId : grouper.id}) 
.exec(function (err, found) { 
    if(!err) console.log(grouper.name + ' - ' + found + ' messages.'); 
}); 

Но есть лучший способ сделать это. Вы выполняете запрос один раз для каждой groupId (НЕ ХОРОШО!), Когда вы можете получить результат в ONE Native Запрос!

Messages.native(function (err, MessageCollecion){ 
    MessageCollecion.aggregate(
    { $group: 
     { _id: '$groupId', total_messages: { $sum: 1 } } 
    }, 
    function (err, res) { 
     if (!err) console.log(res); 
    }); 
}); 

Это даст вам groupId вместо group name. Таким образом, вы можете запросить один раз для всех групп, а затем получить имя из идентификатора. Тем не менее, 2 queries лучше запросить один раз для каждого groupId.

0

Другим способом сделать это:

var async = require('async'); // npm install async before running Sails 

Group.find().exec(function (err, groups) { 
    if (err) { 
     return next(err); 
    } 
    // Create a group of async tasks 
    var tasks = {}; 

    _.each(groups, function (group) { 
     // For each group, create a task. This task will execute Message.count() 
     // for the specified group. Once done, the task will pass on its results 
     // to a callback. The task is NOT started right away. 
     tasks[group.name] = (function(_groupId) { 
      return function(callback) { 
       Messages.count({groupId: _groupId}).exec(callback); 
      } 
     })(group.id); 
    }); 

    // Now start the tasks, executing them in sequence, one after the other. 
    // At the end, the callback passed to async.series() gets an aggregate 
    // of all the individual tasks' results in its results parameter. 
    async.series(tasks, function(err, results) { 
     // send the results as JSON. 
     res.json(results); 
    }); 

}); 

Надеется, что это помогает. Другой способ сделать это (и проще) - определить ассоциации между вашими моделями. Например. в api/models/Group.js:

// Group model 
module.exports = { 
    attributes: { 
     ..., 
     messages : { collection: 'Messages', via: 'group' }, 
     ... 
    } 
}; 

И в api/models/Messages.js:

// Messages model 
module.exports = { 
    attributes: { 
     ..., 
     group : { model: 'Group' }, 
     ... 
    } 
}; 

Затем вы можете использовать запрос, чтобы получить группы и связанные с ними сообщения как заселенных значения см Waterline reference - populated values:

Group.find() 
.populate('messages') // a "collection" association 
.exec(function (err, groups){ 
    // Now each group in groups has a populated messages attribute 
}); 
Смежные вопросы