Как использовать операторы агрегации MongoDB «$ match» для сопоставления с идентификатором встроенного документа?

Сценарий: рассмотрим документ, присутствующий в MongoDB в коллекции с именем MyCollection.

       {
         "_id" : ObjectId("512bc95fe835e68f199c8686"),
         "author": "dave",
         "score" : 80,
         "USER" : {
                   "UserID": "Test1",
                   "UserName": "ABCD"
                  }
       },
       { "_id" : ObjectId("512bc962e835e68f199c8687"),
         "author" : "dave",
         "score" : 85,
         "USER" : {
                   "UserID": "Test2",
                   "UserName": "XYZ"
                  }
       },
       ...

Я знаю UserID и хочу получить на его основе.

Проблема. Я попробовал следующий код с драйвером Node.js + MongoDB:

   db.Collection('MyCollection', function (err, collection) {
        if (err) return console.error(err); 
        collection.aggregate([
                         { $match: { '$USER.UserID': 'Test2'} }, 
                        {$group: {
                            _id: '$_id' 
                        }
                    },
                        {
                            $project: {
                                _id: 1 
                            }
                        }
                      ], function (err, doc) {
                          if (err) return console.error(err);
                          console.dir(doc); 
                      });
           });

Но это не работает, как ожидалось.

Вопрос: кто-нибудь знает, как сделать то же самое с оператором $match в запросе MongoDB?


Обновление: я не получаю никаких ошибок. Но объект будет пустым, т.е. []


person Amol M Kulkarni    schedule 16.04.2013    source источник
comment
Выньте доллар из $USER.UserID, оператор $match работает точно так же, как обычный запрос   -  person Sammaye    schedule 16.04.2013
comment
Даже после удаления $ я все еще получаю [ ]   -  person Amol M Kulkarni    schedule 16.04.2013
comment
Какая у вас версия MongoDB? Я использую 2.4, и это сработало для меня.   -  person gustavohenke    schedule 16.04.2013


Ответы (1)


Я пытался в оболочке, и ваше утверждение $match неверно - попробуйте в оболочке

> db.MyCollection.find()
{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "USER" : { "UserID" : "Test1", "UserName" : "ABCD" } }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "USER" : { "UserID" : "Test2", "UserName" : "XYZ" } }
> db.MyCollection.aggregate([{$match: {"$USER.UserID": "Test2"}}])
{ "result" : [ ], "ok" : 1 }
> db.MyCollection.aggregate([{$match: {"USER.UserID": "Test2"}}])
{
    "result" : [
        {
            "_id" : ObjectId("512bc962e835e68f199c8687"),
            "author" : "dave",
            "score" : 85,
            "USER" : {
                "UserID" : "Test2",
                "UserName" : "XYZ"
            }
        }
    ],
    "ok" : 1
}

Таким образом, полная агрегация будет:

db.MyCollection.aggregate([
  {$match: {"USER.UserID": "Test2"}},
  {$group: {"_id": "$_id"}},
  {$project: {"_id": 1}}
])

(Вам не нужны дополнительные $project, так как вы проецируете только _id в $group, но так же, как _id уникален, вы должны просто иметь $project и удалить $group)

person Ross    schedule 16.04.2013