如何在 Mongoose 聚合管道中展开/填充数组

问题描述 投票:0回答:1

我正在与 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个附件。

mongodb mongoose aggregation-framework aggregation
1个回答
0
投票

此聚合应该会为您提供所需的输出。

  1. $match
    :您想要的
    ticket
    。请注意
    new mongoose.Types.ObjectId()
    构造函数的使用,这样您就不必使用
    $expr
    并转换
    $toObjectId
  2. $set
    comments
    的输出的
    $filter
    数组仅匹配
    comments
    ,且
    _id
    等于
    ObjectId("6678d63114c2fef2955395f0")
  3. $unwind
    :下一阶段的
    comments
    数组。因为您匹配了
    _id
    ,所以应该只有一个对象。
  4. $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")
            ]
          }
        }
      }
    }
  }
]);

请参阅此处了解工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.