mongodb $ unwind дает несколько результатов - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь $ раскрутить массив истории в схеме, но он создает несколько родительских объектов, вот фрагмент агрегации

[{$lookup: {
  from: 'places',
  localField: 'place',
  foreignField: '_id',
  as: 'placeInfo'
}}, {$unwind: {
  path: '$offers'
}}, {$unwind: {
  path: '$history'
}}, {$lookup: {
      from: 'users',
      localField: 'user',
      foreignField: '_id',
      as: 'userInfo'
}}, {$lookup: {
  from: 'countries',
  localField: 'deliveryAddress.country',
  foreignField: '_id',
  as: 'countryInfo'
}}, {$lookup: {
  from: 'admins',
  localField: 'history.by.id',
  foreignField: '_id',
  as: 'adminInfo'
}}, {$lookup: {
  from: 'pms',
  localField: 'history.by.id',
  foreignField: '_id',
  as: 'pmInfo'
}}, {$lookup: {
      from: 'offers',
      localField: 'offers.offer',
      foreignField: '_id',
      as: 'offerInfo'
}}, {$project: {
  transactionID: 1,
  totalPrice: 1,
  createdAt: 1,
  note: 1,
  status: 1,
  offers: 1,
  payment: 1,
  deliveryAddress: 1,
  user: 1,
  offersQuantity: {
    $sum: '$offers.quantity'
  },
  productsQuantity: {
    $sum: '$products.quantity'
  },
  place: {
    name: {
      $arrayElemAt: ['$placeInfo.name.en', -1]
    },
    branch: {
      $arrayElemAt: ['$placeInfo.branchName.en', -1]
    },
    id: {
      $arrayElemAt: ['$placeInfo._id', -1]
    }
  },
  user: {
    firstName: {
      $arrayElemAt: ['$userInfo.firstName', -1]
    },
    lastName: {
      $arrayElemAt: ['$userInfo.lastName', -1]
    },
    mobile: {
      $arrayElemAt: ['$userInfo.mobile', -1]
    },
    id: {
      $arrayElemAt: ['$userInfo._id', -1]
    }
  },
  deliveryAddress: {
    country: {
      name: {
        $arrayElemAt: ['$countryInfo.name.en', -1]
      },
      id: {
        $arrayElemAt: ['$countryInfo._id', -1]
      }
    },
      city: 1,
      area: 1,
      address: 1,
      nearestLandmark: 1
  },
  offers: [{
    quantity: '$offers.quantity',
    price: '$offers.price',
    offerDetails: {
      $arrayElemAt: ['$offerInfo', -1]
    },
  }],
  history: [{
    status: '$history.status',
    createdAt: '$history.createdAt',
    by: {
      id: '$history.by.id',
      role: '$history.by.role',
      USER: {
        $arrayElemAt: ['$userInfo', -1]
      },
      ADMIN: {
        $arrayElemAt: ['$adminInfo', -1]
      },
      PM: {
        $arrayElemAt: ['$pmInfo', -1] 
      }
    }
  }]
}}, {$match: {
 _id: ObjectId('5e26e21bd1774f60d6947aab')
}}]

и вывод:

_id:5e26e21bd1774f60d6947aab
totalPrice:5000
deliveryAddress:Object
transactionID:"Q-21"
user:Object
place:Object
status:"DELIVERING"
createdAt:2020-01-21T11:35:55.386+00:00
offers:Array
offersQuantity:10
productsQuantity:0
**history**: 

status:"PENDING"
createdAt:2020-01-21T11:34:40.682+00:00
by:Object
id:5db039c8082b8b00132b7a62
role:"USER"
USER:Object


...rest of payload
history: status:"RECEIVED"
createdAt:2020-01-21T11:34:40.682+00:00
by:Object
id:5d7908e37c20a500131d133b
role:"ADMIN"
USER:Object
ADMIN:Object

...res of payload 
history: status:"CANCELLED"
createdAt:2020-01-21T15:04:27.812+00:00
by:Object
id:5d7908e37c20a500131d133b
role:"ADMIN"
USER:Object
ADMIN:Object

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

...rest of payload,
history: [{
status:"PENDING"
createdAt:2020-01-21T11:34:40.682+00:00,
...
}, {
status:"RECEIVED"
createdAt:2020-01-21T11:34:40.682+00:00,
...
}, {
status:"CANCELLED"
createdAt:2020-01-21T15:04:27.812+00:00,
...
}]

1 Ответ

0 голосов
/ 22 января 2020

Это обычное поведение оператора $ unwind

https://docs.mongodb.com/manual/reference/operator/aggregation/unwind

Если вы хотите сгруппировать объекты после операции $ unwind, вы должны сделать что-то вроде этого

{
  $group:
     {
        _id: "$offers"
        ...
     }
}

https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/#group по-размотанным значениям

Все из официальной документации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...