Как получить количество элементов в массиве документов - MongoDB?

У меня есть следующая коллекция MongoDB (JSON):

{
    "_id" : ObjectId("570185458351bbac27bc9a20"),
    "email" : "[email protected]",
    "applicants" : [
            {
                    "id" : "570724e4ae4f8a5026156999",
                    "email" : "[email protected]",
            },
            {
                    "id" : "570724e4ae4f8a5026156333",
                    "email" : "[email protected]",
            },
            {
                    "id" : "570724e4ae4f8a5026156111",
                    "email" : "[email protected]",
            },
            {
                    "id" : "570724e4ae4f8a5026156222",
                    "email" : "[email protected]",
            }
    ],
}, 
{
    "_id" : ObjectId("570185458351bbac27bc9a20"),
    "email" : "[email protected]",
    "applicants" : [
            {
                    "id" : "570724e4ae4f8a5026156555",
                    "email" : "[email protected]",
            },
            {
                    "id" : "570724e4ae4f8a5026156666",
                    "email" : "[email protected]",
            },
    ],
},
{
    "_id" : ObjectId("570185458351bbac27bc9a20"),
    "email" : "[email protected]",
    "applicants" : [
            {
                    "id" : "570724e4ae4f8a5026156555",
                    "email" : "[email protected]",
            },
            {
                    "id" : "570724e4ae4f8a5026156666",
                    "email" : "[email protected]",
            },
    ],
 }

Я хотел бы получить количество элементов во всех массивах документа, где адрес электронной почты = [email protected]. Как я могу получить этот счет?

Я использую следующее, чтобы получить количество документов с электронной почтой [email protected], используя это:

   collection.count({"email" : tmpEmail},    function (err, count) {
      res.json(count);
      console.log("Number: " + count);
    }); 

Как я могу продолжить и подсчитать количество элементов во всех массивах кандидатов для документов, где адрес электронной почты [email protected]? Может для приведенного выше примера будет: 6.

РЕДАКТИРОВАТЬ:

В соответствии с одним из ответов я изменил свой запрос на следующее:

Ответ 1:

collection.aggregate(
        {$match: {"email": req.user.username, "status" : "true"}},
        {$unwind: "$applicants"},
        {$group: {_id:null, count: {$sum :1}},  function (err, count) {
            res.json(count);
            console.log("Number of New Applicants: " + count);
            }
        });

Ответ 2:

collection.aggregate(
        [{$match:{"email" : req.user.username, "status" : "true"}}, 
         {$project:{_id:0, email:1, totalApplicants:{$size:"$applicants"}}},  
         {$group:{_id:"$employer", count:{$sum:"$totalApplicants"}}}],
         function (err, count){
             res.json(count);
             console.log("Number of New Applicants: " + count);
         });

person user2573690    schedule 06.05.2016    source источник


Ответы (2)


Вместо этого вы можете использовать агрегированный запрос:

collection.aggregate(
    [{$match: {"email": req.user.username, "status" : "true"}},
    {$unwind: "$applicants"},
    {$group: {_id:null, count: {$sum :1}}}],  function (err, result) {
        console.log(result);
        console.log("Number of New Applicants: " + result[0].count);
        if(result.length > 0)
            res.json(result[0]);
        else
            res.json({count:0});
        }
    });

В результате вы получите один документ, в котором count будет иметь требуемый результат.

person Sarath Nair    schedule 06.05.2016
comment
Кажется, это не работает, я немного изменил запрос, но каждый раз, когда он вызывается, я получаю ошибку 500 в node. Я добавил обновленный запрос в свой пост. Есть идеи, что может быть не так? - person user2573690; 07.05.2016
comment
см. мою правку. Если все еще не работает, сообщите мне вывод результата. результат всегда будет массивом, и вам, возможно, придется проверить, больше ли длина результата 0 - person Sarath Nair; 09.05.2016
comment
Ошибка, которую я получаю с измененным запросом, это TypeError: collection.aggregate не является функцией. Из того, что я читал в Интернете об этом, обычно это связано с тем, что агрегатная функция не имеет обратного вызова, но в этом случае она есть, функция (ошибка, результат) правильная? Мне также нужно было добавить дополнительный } после {$sum :1} - person user2573690; 10.05.2016

Для этого может потребоваться написать агрегацию, так как вам нужно подсчитать размер массива соискателей, сгруппированного по электронной почте:

Вот эквивалентный запрос mongodb, который возвращает ожидаемое электронное письмо со счетчиком:

db.yourCollection.aggregate(

  [{$match:{"email" : "[email protected]"}}, 

  {$project:{_id:0, email:1,totalEmails:{$size:"$applicants"}}},  

  {$group:{_id:"$email", count:{$sum:"$totalEmails"}}}])

Это возвращает { "_id" : "[email protected]", "count" : 6 }

Возможно, вам придется изменить это в соответствии с вашим кодом.

person Atish    schedule 06.05.2016
comment
Я пробовал это, и я не могу заставить его работать, мне нужно было немного изменить запрос, но все равно не повезло. Я обновил свой исходный пост с запросом, который я пробовал. - person user2573690; 07.05.2016