1

рассмотрения этих документов:документы группы MongoDB и ограничить каждую группу

{ 
    "Field1":"Test_1", 
    "Speaker":1, 
    "Listener":2, 
    "ListenTime": ISODate("2016-10-15T14:17:49.336Z") 
}, 
{ 
    "Field1":"Test_2", 
    "Speaker":1, 
    "Listener":2, 
    "ListenTime": ISODate("2016-10-13T14:17:49.336Z") 
}, 
{ 
    "Field1":"Test_3", 
    "Speaker":1, 
    "Listener":3, 
    "ListenTime": ISODate("2016-10-10T14:10:49.336Z") 
} 

Что я, что нужно сделать, это извлечь с помощью одного запроса в MongoDB (3.2) только те документы, группируя их по говорящим и слушающим, принимая только документ со старейшим ListenTime.
Таким образом, в этом случае результат будет:

{ 
    "Field1":"Test_1", 
    "Speaker":1, 
    "Listener":2, 
    "ListenTime": ISODate("2016-10-15T14:17:49.336Z") 
}, 
{ 
    "Field1":"Test_3", 
    "Speaker":1, 
    "Listener":3, 
    "ListenTime": ISODate("2016-10-10T14:10:49.336Z") 
} 

Можно ли сделать это с помощью одного запроса?

+0

Пожалуйста сообщению вы уже пробовали? –

ответ

1

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

db.collection.aggregate([ 
    { "$sort": { "ListenTime": -1 } }, 
    { 
     "$group": { 
      "_id": { 
       "Speaker": "$Speaker", 
       "Listener": "$Listener" 
      }, 
      "Field1" : { "$first": "$Field1" }, 
      "ListenTime" : { "$first": "$ListenTime" } 
     } 
    }, 
    { 
     "$project": { 
      "Field1": 1, 
      "Speaker": "$_id.Speaker", 
      "Listener": "$_id.Listener", 
      "ListenTime": 1, 
      "_id": 0 
     } 
    } 
]) 

Пример вывода

/* 1 */ 
{ 
    "Field1" : "Test_3", 
    "ListenTime" : ISODate("2016-10-10T14:10:49.336Z"), 
    "Speaker" : 1, 
    "Listener" : 3 
} 

/* 2 */ 
{ 
    "Field1" : "Test_1", 
    "ListenTime" : ISODate("2016-10-15T14:17:49.336Z"), 
    "Speaker" : 1, 
    "Listener" : 2 
} 
1

Для достижения этой цели может быть использована структура агрегации. На первом этапе используйте $group для группировки документов с помощью динамиков и слушателей. На этом этапе добавьте все документы в группу в список, используя оператор $push, и с помощью оператора $max вычислите недавний ListenTime. Следуйте этому, на этапе $redact, чтобы сохранить документ с недавним ListenTime в списке. Затем используйте этап $unwind, чтобы сгладить список в документы. Затем используйте конечный этап $project, чтобы получить нужные поля.

Запрос на агрегацию будет выглядеть следующим образом.

db.sampleCollection.aggregate([ 
    { 
     "$group":{ 
      "_id":{"Speaker":"$Speaker", "Listener":"$Listener"}, 
      ListenTime : {"$max":"$ListenTime"}, 
      "docs":{"$push":"$$ROOT"} 
     } 
    }, 
    { 
     $redact:{ 
      $cond:[{$eq:["$ListenTime","$$ROOT.ListenTime"]},"$$DESCEND","$$PRUNE"] 
     } 
    }, 

    { 
     "$project":{ 
      "ListenTime":1, 
      "Field1":"$docs.0.Field1", 
      "Speaker":"$docs.0.Speaker", 
      "Listener":"$docs.0.Listener" 
     } 
    } 
]) 

Пример вывода:

{ 
     "ListenTime" : ISODate("2016-10-10T14:10:49.336Z"), 
     "Field1" : "Test_3", 
     "Speaker" : 1, 
     "Listener" : 3 
} 
{ 
     "ListenTime" : ISODate("2016-10-15T14:17:49.336Z"), 
     "Field1" : "Test_1", 
     "Speaker" : 1, 
     "Listener" : 2 
} 
Смежные вопросы