【问题标题】:How to add a property as an object in grouped array (mongodb aggregation)?如何在分组数组(mongodb聚合)中添加属性作为对象?
【发布时间】:2022-01-01 22:10:04
【问题描述】:

我是猫鼬的新手,遇到了一些问题。我有 2 个实例:患者和预约。它们看起来像:

const AppointmentSchema = new mongoose.Schema({
  patient: { type: Schema.Types.ObjectId, ref: 'Patient' },
  dentNumber: Number,
  diagnosis: String,
  price: Number,
  date: String,
  time: String
}, {
  timestamps: true
});

const PatientSchema = new mongoose.Schema({
  fullname: String,
  phone: String,
}, {
  timestamps: true
});

PatientSchema.virtual('Appointments', {
  ref: 'Appointment',
  localField: '_id',
  foreignField: 'patient',
  justOne: false
})

约会数据如下所示:

{
    "success": true,
    "data": [
        {
            "_id": "61cb1cad610963c75f7e41a2",
            "patient": {
                "_id": "61c045bcb0c7e68c96e6ba0e",
                "fullname": "test 126",
                "phone": "+7 123 54 55",
                "createdAt": "2021-12-20T08:58:36.776Z",
                "updatedAt": "2021-12-20T08:58:36.776Z",
                "__v": 0
            },
            "dentNumber": 33,
            "diagnosis": "String3",
            "price": 500,
            "date": "18-10-2021",
            "time": "15:50",
            "createdAt": "2021-12-28T14:18:21.537Z",
            "updatedAt": "2021-12-28T14:24:29.576Z",
            "__v": 0
        },
        {
            "_id": "61cc26bd7d1e9476e52c4b35",
            "patient": {
                "_id": "61c045bcb0c7e68c96e6ba0e",
                "fullname": "test 126",
                "phone": "+7 123 54 55",
                "createdAt": "2021-12-20T08:58:36.776Z",
                "updatedAt": "2021-12-20T08:58:36.776Z",
                "__v": 0
            },
            "dentNumber": 4,
            "diagnosis": "String3",
            "price": 1600,
            "date": "17-10-2021",
            "time": "16:50",
            "createdAt": "2021-12-29T09:13:33.575Z",
            "updatedAt": "2021-12-29T09:13:33.575Z",
            "__v": 0
        },
        {
            "_id": "61cc3663970d00f9129d0456",
            "patient": {
                "_id": "61c045bcb0c7e68c96e6ba0e",
                "fullname": "test 126",
                "phone": "+7 123 54 55",
                "createdAt": "2021-12-20T08:58:36.776Z",
                "updatedAt": "2021-12-20T08:58:36.776Z",
                "__v": 0
            },
            "dentNumber": 5,
            "diagnosis": "String4",
            "price": 1700,
            "date": "18-10-2021",
            "time": "17:50",
            "createdAt": "2021-12-29T10:20:19.257Z",
            "updatedAt": "2021-12-29T10:20:19.257Z",
            "__v": 0
        },
     ]
}

我需要以这种方式按日期对约会进行排序:

  await Appointment
    .aggregate([
      { $group: {
        _id: "$date",
          data: { $push: {
            id: "$_id",
            patientId: "$patient",
            //patient: { patient: await Patient.findById(mongoose.Types.ObjectId.fromString("$patient")) },
            dentNumber: "$dentNumber",
            diagnosis: "$diagnosis",
            price: "$price",
            date: "$date",
            time: "$time"
          } }
      } },
      { $sort: { _id: 1 } },
    ])

在此之后,我得到了正确形式的答案:

{
    "success": true,
    "data": [
        {
            "_id": "17-10-2021",
            "data": [
                {
                    "id": "61cb1cad610963c75f7e41a2",
                    "patientId": "61c045bcb0c7e68c96e6ba0e",
                    "dentNumber": 33,
                    "diagnosis": "String3",
                    "price": 500,
                    "date": "17-10-2021",
                    "time": "15:50"
                },
                {
                    "id": "61d1651b25ab055c5cc913ac",
                    "patientId": "61be3e6b51b968aa92d5e248",
                    "dentNumber": 5,
                    "diagnosis": "String4",
                    "price": 1750,
                    "date": "17-10-2021",
                    "time": "19:35"
                }
            ]
        },
        {
            "_id": "18-10-2021",
            "data": [
                {
                    "id": "61cc26bd7d1e9476e52c4b35",
                    "patientId": "61c045bcb0c7e68c96e6ba0e",
                    "dentNumber": 4,
                    "diagnosis": "String3",
                    "price": 1600,
                    "date": "18-10-2021",
                    "time": "16:50"
                },
            ]
        },

但是我需要以某种方式获得一个完整的对象 Patient,而不是属性 "patientId"。使数据看起来像这样:

{
    "success": true,
    "data": [
        {
            "_id": "17-10-2021",
            "data": [
                {
                    "id": "61cb1cad610963c75f7e41a2",
                    "dentNumber": 33,
                    "diagnosis": "String3",
                    "price": 500,
                    "date": "17-10-2021",
                    "time": "15:50",
                    "patient": {
                        "_id": "61c045bcb0c7e68c96e6ba0e",
                        "fullname": "test 126",
                        "phone": "+7 123 54 55",
                        "createdAt": "2021-12-20T08:58:36.776Z",
                        "updatedAt": "2021-12-20T08:58:36.776Z",
                        "__v": 0
                    }
                },
                {
                    "id": "61d1651b25ab055c5cc913ac",
                    "dentNumber": 5,
                    "diagnosis": "String4",
                    "price": 1750,
                    "date": "17-10-2021",
                    "time": "19:35",
                    "patient": {
                        "_id": "61be3e6b51b968aa92d5e248",
                        "fullname": "test 421",
                        "phone": "+7 123-11-22",
                        "createdAt": "2021-12-18T20:02:51.177Z",
                        "updatedAt": "2021-12-28T14:41:45.948Z",
                        "__v": 0
                    }
                }
            ]
        },
        {
            "_id": "18-10-2021",
            "data": [
                {
                    "id": "61cc26bd7d1e9476e52c4b35",
                    "dentNumber": 4,
                    "diagnosis": "String3",
                    "price": 1600,
                    "date": "18-10-2021",
                    "time": "16:50",
                    "patient": {
                        "_id": "61c045bcb0c7e68c96e6ba0e",
                        "fullname": "test 126",
                        "phone": "+7 123 54 55",
                        "createdAt": "2021-12-20T08:58:36.776Z",
                        "updatedAt": "2021-12-20T08:58:36.776Z",
                        "__v": 0
                    }
                }
            ]
        },
    ]
}

【问题讨论】:

  • 我不会通过提供内部字段作为输入来支持外部查询,您必须使用 $lookup 阶段加入另一个集合,如需更详细的答案,请发布一些集合和预期结果的示例文档。
  • 我添加了一个附加信息,如果你能提供帮助,那就太好了!我尝试使用 $group 管理 $lookup,但无法弄清楚。

标签: mongodb mongoose aggregation-framework


【解决方案1】:

不能通过在任何查询中传递内部字段来执行另一个查询,您需要在组之前进行查找操作,

  • $lookup 与患者集合,传递 patient 作为 localField 并传递 _id 作为 foreignField
  • $group 阶段,使用$first 从患者的查找结果中获取第一个元素
await Appointment.aggregate([
  {
    $lookup: {
      from: "patient",
      localField: "patient", // change to your exact collection name
      foreignField: "_id",
      as: "patient"
    }
  },
  {
    $group: {
      _id: "$date",
      data: {
        $push: {
          id: "$_id",
          patientId: { $first: "$patient._id" },
          patient: { $first: "$patient" },
          dentNumber: "$dentNumber",
          diagnosis: "$diagnosis",
          price: "$price",
          date: "$date",
          time: "$time"
        }
      }
    }
  },
  { $sort: { _id: 1 } }
])

Playground

【讨论】:

    猜你喜欢
    • 2018-04-20
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 2023-01-20
    相关资源
    最近更新 更多