2015-03-18 2 views
0

В настоящее время я использую MonGODB v2.6.4 только по той причине, что Robomongo пока не поддерживает MongoDB v3.0.Как вернуть весь документ из агрегирования

Использование следующих примеров документов, которые не являются тем, как я мог бы их структурировать, если бы это не был сокращен пример того, что я пытаюсь сделать.

db.visitors.insert({ 
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-01 17:05:00")}, 
       {"building" : "building02", "lastVisit" : new ISODate("2015-02-04 04:25:00")}, 
       {"building" : "building03", "lastVisit" : new ISODate("2015-02-07 15:45:00")}, 
       {"building" : "building04", "lastVisit" : new ISODate("2015-02-10 15:45:00")} 
       ], 

"firstName" : "John", 
"lastName" : "Smith", 
"gender" : "male", 
"accountNumber" : "123456789", 
}); 

db.visitors.insert({ 
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-02 17:05:00")}, 
       {"building" : "building02", "lastVisit" : new ISODate("2015-02-05 04:25:00")}, 
       {"building" : "building03", "lastVisit" : new ISODate("2015-02-08 15:45:00")}, 
       {"building" : "building04", "lastVisit" : new ISODate("2015-02-11 15:45:00")} 
       ], 

"firstName" : "Jane", 
"lastName" : "Smith", 
"gender" : "female", 
"accountNumber" : "987654321", 
}); 

db.visitors.insert({ 
    "visits" : [{"building" : "building01", "lastVisit" : new ISODate("2015-02-03 17:05:00")}, 
       {"building" : "building02", "lastVisit" : new ISODate("2015-02-06 04:25:00")}, 
       {"building" : "building03", "lastVisit" : new ISODate("2015-02-09 15:45:00")}, 
       {"building" : "building04", "lastVisit" : new ISODate("2015-02-12 15:45:00")} 
       ], 

"firstName" : "James", 
"lastName" : "Smith", 
"gender" : "male", 
"accountNumber" : "123056780", 
}); 

Я хочу найти последнего посетителя в конкретном здании и вам нужен весь документ для возвращения этого посетителя.

Я разработал это агрегирование запроса, который почти делает то, что я хочу:

db.visitors.aggregate([ 
    {$match: {"visits.building": "building02"}}, 
    {$unwind: "$visits"}, 
    {$project: {"visitorId": "$_id", "building": "$visits.building", "lastVisit": "$visits.lastVisit"}}, 
    {$sort: {"lastVisit": 1}}, 
    {$group: {"_id": "$building", "visitorId": {$last: "$visitorId"}, "lastVisit": {$last: "$lastVisit"}}}, 
    {$match: {"_id": "building02"}}, 
    {$limit: 1} 
]) 

и возвращает эту структуру:

{ 
    "result" : [ 
     { 
      "_id" : "building02", 
      "visitorId" : ObjectId("55098990ca5b44f2858f4cb5"), 
      "lastVisit" : ISODate("2015-02-12T15:45:00.000000:00") 
     } 
    ], 
    "ok" : 1.0000000000000000 
} 

Как я могу изменить совокупный запрос, чтобы вернуть все документ посетителя не только посетителя? Я пробовал (и не использовал $$ROOT и $$CURRENT).

Если возврат документа целиком невозможен, как я могу сделать поиск в возвращаемой структуре результатов, чтобы получить его по идентификатору? Я пытался вариации на эту тему:

var result = db.visitors.aggregate([ 
    {$match: {"visits.building": "building02"}}, 
    {$unwind: "$visits"}, 
    {$project: {"visitorId": "$_id", "building": "$visits.building", "lastVisit": "$visits.lastVisit"}}, 
    {$sort: {"lastVisit": 1}}, 
    {$group: {"_id": "$building", "visitorId": {$last: "$visitorId"}, "lastVisit": {$last: "$lastVisit"}}}, 
    {$match: {"_id": "building02"}}, 
    {$limit: 1} 
]) 

db.individuals.find({_id: {$eq: {result.visitorId: {$slice: [0, 1]}}}}) 

Я бы предпочел, чтобы сделать все это в одном запросе, но если я не могу, я не могу.

ответ

1

Вам не нужно $ group, поэтому вам не нужно беспокоиться о $$ROOT или пытаться вернуть все поля. Вы вернетесь (копия) оригинального документа с самым последним посещением, оставшимся в массиве visits.

> db.visitors.aggregate([ 
    { "$match" : { "visits.building" : "building02" } }, 
    { "$unwind" : "$visits" }, 
    { "$match" : { "visits.building" : "building02" } }, 
    { "$sort" : { "visits.lastVisit" : -1 } }, { "$limit" : 1 } 
]) 
{ 
    "_id" : ObjectId("5509e963b8b4702f49ffcee6"), 
    "visits" : { 
     "building" : "building02", 
     "lastVisit" : ISODate("2015-02-06T04:25:00Z") 
    }, 
    "firstName" : "James", 
    "lastName" : "Smith", 
    "gender" : "male", 
    "accountNumber" : "123056780" 
} 

Если вы хотите, чтобы все visits массива, то я бы просто проецировать _id по трубопроводу и не находка с ним после возвращения трубопровода, чтобы получить весь документ.

+0

Таким образом, группа $ в моем запросе была ненужной, а $ project фактически скрывал результат, который я хотел. DOH! Ваши изменения дают мне именно то, что я хочу, спасибо. – BraileTrail

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