Уменьшите вложенный массив в объект с помощью пользовательской формулы, агрегации MongoDB

#mongodb #reduce #sub-array

Вопрос:

Я ищу способ уменьшить массив элементов в объект на основе пользовательских требований.

Рассматривая коллекцию, подобную:

 [
 { 
   name: "David",
   checkins: [
       {
          _id: "612e162d439cb04934d13f9e",
          in_at: "2021-09-12T08:02:00.000Z",
          out_at: "2021-09-12T09:03:00.000Z"
       },
       {
          _id: "612e162d439cb04934d13f9f",
          in_at: "2021-09-12T10:04:00.000Z",
          out_at: "2021-09-12T11:05:00.000Z"
       },
       {
          _id: "612e162d439cb04934d13f9g",
          in_at: "2021-09-12T12:02:00.000Z",
          out_at: "2021-09-12T14:03:00.000Z"
       }
   ] 
 },
 { 
   name: "Wilson",
   checkins: [
       {
          _id: "612e162d439cb04934d13f9e",
          in_at: "2021-09-12T08:02:00.000Z",
          out_at: "2021-09-12T09:03:00.000Z"
       },
       {
          _id: "612e162d439cb04934d13f9f",
          in_at: "2021-09-12T11:04:00.000Z",
          out_at: "2021-09-12T12:05:00.000Z"
       },
       {
          _id: "612e162d439cb04934d13f9g",
          in_at: "2021-09-12T13:02:00.000Z",
          out_at: "2021-09-12T14:03:00.000Z"
       }
   ]  
 }
]
 

Теперь мне нужно, чтобы уменьшить массив чекинов в один объект и присоединить его к новой проверке свойств. Просто нужно объединить первый элемент массива и последний элемент массива. если у вас есть только один элемент, просто нужно использовать его, если массив пуст, проверка должна быть нулевой. выходной объект должен быть:

 {
   _id: 1st_element_id,
   in_at: 1st_element_in_at,
   out_at: last_emenet_out_at
}
 

Таким образом, в соответствии с примером ожидаемый результат:

 [
        {
            name: "David",
            checkin: {
                _id: "612e162d439cb04934d13f9e",
                in_at: "2021-09-12T08:02:00.000Z",
                out_at: "2021-09-12T14:03:00.000Z"
            }
        },
        {
            name: "Wilson",
            checkin: {
                _id: "612e162d439cb04934d13f9e",
                in_at: "2021-09-12T08:02:00.000Z",
                out_at: "2021-09-12T14:03:00.000Z"
            }
        }
]
 

Ценю любую помощь, спасибо!

Ответ №1:

  • $first чтобы получить первый элемент массива
  • $last чтобы получить последний элемент массива
  • $mergeObjects чтобы объединить первый и последний out_at объекты свойств
 db.collection.aggregate([
  {
    $addFields: {
      checkin: {
        $mergeObjects: [
          {
            $first: "$checkins"
          },
          {
            out_at: {
              $last: "$checkins.out_at"
            }
          }
        ]
      }
    }
  }
])
 

Игровая площадка