我正在与 Mongoose 合作,并尝试在聚合管道中展开/填充 comments.attachments 字段。这是我的代码的相关部分:
const result = await Ticket.aggregate([
{ $match: { $expr: { $eq: ['$_id', { $toObjectId: "667293eca3a67d7c5d9ff1e2" }] } } },
{ $unwind: '$comments' },
{ $match: { $expr: { $eq: ['$comments._id', { $toObjectId: "667382f627df37eb4e7a3220" }] } } },
])
此查询成功检索票证文档并展开评论数组。但是,即使存在与评论关联的附件,comments.attachments 字段仍然是一个空数组。
[
{
_id: new ObjectId('667293eca3a67d7c5d9ff1e2'),
referenceNo: 'TCK_06-19-2024_0001',
subject: new ObjectId('6670dad080ea03a681f70295'),
description: 'pero ang totoo, di bali na ako. ikaw lang iniisip ko.',
priority: 'medium',
status: 'open',
initiator: new ObjectId('6670da9d80ea03a681f70292'),
createdBy: new ObjectId('667106fff8abeeb0d87341ba'),
assignedTo: null,
attachments: [ [Object], [Object] ],
comments: {
userId: new ObjectId('6670db4180ea03a681f7029e'),
content: '2nd comment w atta',
attachments: [Array],
_id: new ObjectId('667382f627df37eb4e7a3220'),
createdAt: 2024-06-20T01:16:38.190Z,
updatedAt: 2024-06-20T01:16:38.190Z
},
createdAt: 2024-06-19T08:16:44.129Z,
updatedAt: 2024-06-20T02:14:51.282Z,
__v: 0
}
]
以下是我的模型供参考:
门票型号
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ticketCommentSchema = require('./ticketCommentModel');
const ticketAttachmentSchema = require('./ticketAttachmentModel');
const ticketSchema = new Schema({
// ... other schema properties
comments: [ticketCommentSchema],
attachments: {
type: [ticketAttachmentSchema],
required: true,
validate: [attachmentsArray => attachmentsArray.length > 0, 'At least one attachment is required']
},
}, {
timestamps: true
});
module.exports = mongoose.model('Ticket', ticketSchema);
票评模型
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ticketAttachmentSchema =
require('./ticketAttachmentModel');
const ticketCommentSchema = new Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
content: {
type: String,
trim: true,
required: true
},
attachments: [ticketAttachmentSchema]
}, {
timestamps: true
});
module.exports = ticketCommentSchema;
票据附件模型
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ticketAttachmentSchema = new Schema({
// ... attachment schema properties
}, {
timestamps: true
});
module.exports = ticketAttachmentSchema;
我的问题是:
如何修改聚合管道以展开或填充 comments.attachments 字段并检索查询结果中的附件详细信息?
我在网上搜索了解决方案,但没有找到任何特定于这种情况的内容。任何帮助将不胜感激!
我尝试这个聚合管道
const result = await Ticket.aggregate([
{ $match: { $expr: { $eq: ['$_id', { $toObjectId: "667293eca3a67d7c5d9ff1e2" }] } } },
{ $unwind: '$comments' },
{ $match: { $expr: { $eq: ['$comments._id', { $toObjectId: "667382f627df37eb4e7a3220" }] } } },
{
$unwind: {
path: "$comments.attachments",
preserveNullAndEmptyArrays: true
}
},
])`
它返回此数据
[
{
_id: new ObjectId('667293eca3a67d7c5d9ff1e2'),
referenceNo: 'TCK_06-19-2024_0001',
subject: new ObjectId('6670dad080ea03a681f70295'),
description: 'pero ang totoo, di bali na ako. ikaw lang iniisip ko.',
priority: 'medium',
status: 'open',
initiator: new ObjectId('6670da9d80ea03a681f70292'),
createdBy: new ObjectId('667106fff8abeeb0d87341ba'),
assignedTo: null,
attachments: [ [Object], [Object] ],
comments: {
userId: new ObjectId('6670db4180ea03a681f7029e'),
content: '2nd comment w atta',
attachments: [Object],
_id: new ObjectId('667382f627df37eb4e7a3220'),
createdAt: 2024-06-20T01:16:38.190Z,
updatedAt: 2024-06-20T01:16:38.190Z
},
createdAt: 2024-06-19T08:16:44.129Z,
updatedAt: 2024-06-20T02:14:51.282Z,
__v: 0
},
{
_id: new ObjectId('667293eca3a67d7c5d9ff1e2'),
referenceNo: 'TCK_06-19-2024_0001',
subject: new ObjectId('6670dad080ea03a681f70295'),
description: 'pero ang totoo, di bali na ako. ikaw lang iniisip ko.',
priority: 'medium',
status: 'open',
initiator: new ObjectId('6670da9d80ea03a681f70292'),
createdBy: new ObjectId('667106fff8abeeb0d87341ba'),
assignedTo: null,
attachments: [ [Object], [Object] ],
comments: {
userId: new ObjectId('6670db4180ea03a681f7029e'),
content: '2nd comment w atta',
attachments: [Object],
_id: new ObjectId('667382f627df37eb4e7a3220'),
createdAt: 2024-06-20T01:16:38.190Z,
updatedAt: 2024-06-20T01:16:38.190Z
},
createdAt: 2024-06-19T08:16:44.129Z,
updatedAt: 2024-06-20T02:14:51.282Z,
__v: 0
}
]
它将 comment.attachments 转换为对象,但仍然不填充附件的数据, 评论还有3个附件。
此聚合应该会为您提供所需的输出。
$match
:您想要的ticket
。请注意 new mongoose.Types.ObjectId()
构造函数的使用,这样您就不必使用 $expr
并转换 $toObjectId
。$set
:comments
的输出的 $filter
数组仅匹配 comments
,且 _id
等于 ObjectId("6678d63114c2fef2955395f0")
。$unwind
:下一阶段的comments
数组。因为您匹配了 _id
,所以应该只有一个对象。$set
:comments.attachments
的输出的 $filter
数组仅匹配 attachments
,且 _id
等于 ObjectId("6678d63114c2fef2955395f1")
。const result = await Ticket.aggregate([
{
$match: {
_id: new mongoose.Types.ObjectId("6678d3b714c2fef2955395ca"),
"comments._id": new mongoose.Types.ObjectId("6678d63114c2fef2955395f0")
}
},
{
$set: {
comments: {
$filter: {
input: "$comments",
as: "c",
cond: {
$eq: [
"$$c._id",
new mongoose.Types.ObjectId("6678d63114c2fef2955395f0")
]
}
}
}
}
},
{
$unwind: "$comments"
},
{
$set: {
"comments.attachments": {
$filter: {
input: "$comments.attachments",
as: "ca",
cond: {
$eq: [
"$$ca._id",
new mongoose.Types.ObjectId("6678d63114c2fef2955395f1")
]
}
}
}
}
}
]);
请参阅此处了解工作示例。