2013-12-18 5 views
4

first: me -> MongoNoob, и я знаю, что это уже было задано одним или другим способом, но до сих пор я не нашел ничего конкретного. Скажем, у меня есть два Moongoose модели, описанные, как это:Несколько запросов мангуста() запросов к MongoDB

var pollSchema = mongoose.Schema({ 
    title: String, 
    choices: [{ 
     content: String 
    }] 
}); 
var choiceSchema = mongoose.Schema({ 
    poll_id: mongoose.Schema.ObjectId, 
    option: Number 
}); 

пользовательский интерфейс показывает опрос, и когда пользователь выбирает выбор, написано в choiceSchema модели. Теперь я хотел бы создать «статистику», указав, сколько пользователей выбрали вариант 1, вариант 2, вариант 3, ... Я мог бы просто получить все варианты опроса с помощью find и сгенерировать статистику в код сервера, но если у меня будет миллион пользовательских вариантов, мне придется иметь дело с массивом того же размера. Это неправильно. я, однако, может генерировать запрос и использовать count() метод:

var query = Choice.find({poll_id: someId}), 
query.where('option', 1); 
var resultForOption1; 
query.count(function(err, count)) { 
    resultForOption1 = count; 
}); 

Как бы сделать это для нескольких вариантов и «присоединиться» (ха-ха) результаты в массив? Поскольку это все асинхронно, я бы вложил вызовы, но это не вариант для переменного количества запросов.

Пропустить лес для деревьев :-)? Может кто-нибудь указать мне в правильном направлении?

BR, Daniel

+0

Я бы рекомендовал вам создать документ, который записывает результаты совокупности и сохраняет значения, а не пытается подсчитать их в реальном времени. – WiredPrairie

ответ

4

Вы можете использовать aggregate сделать это:

Choice.aggregate(
    {$group: {_id: {poll_id: '$poll_id', option: '$option'}, count: {$sum: 1}}} 
).exec(...); 

Это сгруппирует choices документы сбора по poll_id и option и подсчета вхождений каждого, давая выход, который выглядит следующим образом:

{ 
    "result": [ 
    { 
     "_id": { 
     "poll_id": 2, 
     "option": 3 
     }, 
     "count": 1 
    }, 
    { 
     "_id": { 
     "poll_id": 1, 
     "option": 2 
     }, 
     "count": 2 
    }, 
    { 
     "_id": { 
     "poll_id": 2, 
     "option": 2 
     }, 
     "count": 1 
    }, 
    { 
     "_id": { 
     "poll_id": 1, 
     "option": 1 
     }, 
     "count": 1 
    } 
    ], 
    "ok": 1 
} 

Затем вы можете использовать последующие фазы $group и $project в своем конвейере aggregate для дальнейшей группировки и изменения сформированных документов по мере необходимости.

+0

Большое спасибо. Это точно сделало трюк и позволил мне выйти на новые основания. :-) – Daniel

2

Если вы хотите просто перебирать count запросов и сделать это легко и чистить вы можете использовать LIB как co или даже лучше, асинхр:

async.map({ "option":1 },{ "option":2 }], Choice.find, function(e, r){ 
    // And you continue from here 
}); 

Другой вариант - лучше, по-моему. использовать aggregate queries. Вы узнаете больше о mongoDB и должны быть более эффективными. В ссылке я посылаю к вам первый пример почти то, что вы хотите сделать:

query

Смежные вопросы