Как агрегировать вложенный массив с помощью MongoDB?

#javascript #mongodb #aggregation-framework

Вопрос:

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

Вот мои структуры данных.

Заказ.модель.ts

 const OrderSchema: Schema = new Schema(  {  userId: {  type: String,  require: true,  },  products: [  {  product: {  _id: {  type: String,  },  title: {  type: String,  },  desc: {  type: String,  },  img: {  type: String,  },  categories: {  type: Array,  },  price: {  type: Number,  },  createdAt: {  type: String,  },  updatedAt: {  type: String,  },  size: {  type: String,  },  color: {  type: String,  },  },  quantity: {  type: Number,  default: 1,  },  },  ],  quantity: {  type: Number,  },  total: {  type: Number,  },  address: {  type: String,  require: true,  },  status: {  type: String,  default: 'pending',  },  },  { timestamps: true }, );  

Заказ-сервис.ts

 public async getIncome(productId?: string) {  const date = new Date();  const lastMonth = new Date(date.setMonth(date.getMonth() - 1));  const previousMonth = new Date(new Date().setMonth(lastMonth.getMonth() - 1));  //const lastYear = new Date(date.setFullYear(date.getFullYear() - 1));  const income = await this.order.aggregate([  {  $match: {  createdAt: { $gte: lastMonth },  ...(productId amp;amp; {  products: { $elemMatch: { product: { _id: productId } } },  }),  },  },  {  $project: {  month: { $month: '$createdAt' },  sales: '$total',  },  },  {  $group: {  _id: '$month',  total: { $sum: '$sales' },  },  },  ]);  return income;  }  

Когда я рассчитал все продажи без ProductID , все прошло хорошо , я попытался использовать elemMatch , чтобы найти ProductID , но это не сработает, я что-то пропустил ?

Ответ №1:

Сначала попробуйте $развернуть массив «продукты», затем примените $match:

 const income = await this.order.aggregate([  {  $unwind: '$products'  },  {  $match: {  createdAt: { $gte: lastMonth },  product: { _id: productId },  },  },  {  $project: {  month: { $month: '$createdAt' },  sales: '$total',  },  },  {  $group: {  _id: '$month',  total: { $sum: '$sales' },  },  }, ]);