如何将 属性 作为对象添加到分组数组中(mongodb 聚合)?
How to add a property as an object in grouped array (mongodb aggregation)?
我是猫鼬的新手,遇到了一些问题。我有 2 个实例:Patient 和 Appointment。它们看起来像:
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"
},
]
},
但不是 属性 "patientId"
我需要以某种方式获得一个完整的对象 Patient。使数据看起来像这样:
{
"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
与患者集合,将 patient
作为 localField 传递并将 _id
作为 foreignField
$group
阶段,使用 $first
从 patient 中的查找结果中获取第一个元素
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 } }
])
我是猫鼬的新手,遇到了一些问题。我有 2 个实例:Patient 和 Appointment。它们看起来像:
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"
},
]
},
但不是 属性 "patientId"
我需要以某种方式获得一个完整的对象 Patient。使数据看起来像这样:
{
"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
与患者集合,将patient
作为 localField 传递并将_id
作为 foreignField$group
阶段,使用$first
从 patient 中的查找结果中获取第一个元素
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 } }
])