【问题标题】:mongodb $unwind produces multiple resultsmongodb $unwind 产生多个结果
【发布时间】:2020-05-08 11:29:32
【问题描述】:

我正在尝试 $unwind 架构中的历史数组,但它会产生多个父对象, 这里是聚合sn-p

[{$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,
...
}]

【问题讨论】:

  • 如果您可以在mongoplayground.net 创建沙箱,您就有更多机会获得有效的答案。

标签: node.js mongodb mongoose nosql aggregation-framework


【解决方案1】:

这是$unwind操作符的正常行为

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

如果你想在 $unwind 操作之后对对象进行分组,你应该这样做

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

https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/#group-by-unwound-values

一切均来自官方文档

【讨论】:

    猜你喜欢
    • 2017-10-03
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    相关资源
    最近更新 更多