mongodb $lookup在嵌套字段数组中不工作

hgtggwj0  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(141)

我有这样的通知模式

const mongoose = require("mongoose");

var NotificationsSchema = mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User", //this may be null if user is not in system
  },
  userEmail: {
    type: String,
    //required: [true, "User Email cannot be empty"],
  },
  notifications: [
    {
      _id: mongoose.Schema.Types.ObjectId,
      notificationTemplate: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "NotificationTemplate",
        required: [true, "Notification Template cannot be empty"],
      },
      url: {
        type: String,
        //required: [true, "Message cannot be empty"],
      },
      attachment: {
        type: [String],
      },
      by: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User", //if some other user send me notification
      },
      protocols: {
        type: [
          {
            type: String,
            enum: ["email", "webapp", "smstext"],
          },
        ],
        validate: {
          validator: function (protocols) {
            return protocols.length > 0;
          },
          message: "At least one protocol is required",
        },
        required: [true, "Protocols for Notification cannot be empty"],
      },
      isRead: {
        type: Boolean,
        default: false,
      },
      readOn: {
        type: Date,
      },
      sentWeb: {
        type: Date,
      },
      sentEmail: {
        type: Date,
      },
      sentSmsText: {
        type: Date,
      },
      isDeleted: {
        type: Boolean,
        default: false,
      },
      //Make sure to save all subject and message variable in notificationParameters
      notificationParameters: Object, //here saved any other info
      createdOn: {
        type: Date,
        default: Date.now(),
      },
    },
  ],
  createdDate: {
    type: Date,
    default: Date.now(),
  },
});

let Notifications;

if (!mongoose.models["Notifications"]) {
  Notifications = mongoose.model("Notifications", NotificationsSchema);
} else {
  Notifications = mongoose.models["Notifications"];
}
module.exports = Notifications;

字符串
我试图找到用户通知与分页和填充notificationTemplate,但不知何故,它从来没有填充notificationTemplate字段。每个用户可以有多个文档中。
这是我尝试

const doc = await Notifications.aggregate([
    { $match: { user: mongoose.Types.ObjectId(req.params.userId) } },
    //{ $unwind: "$notifications" },
    { $match: { "notifications.protocols": { $in: ["webapp"] } } },
    {
      $lookup: {
        localField: "notificationTemplate",
        //localField: "notifications.notificationTemplate", //not working
        foreignField: "_id",
        from: "NotificationTemplate", // Replace with the actual collection name
        as: "notificationTemplate",
        // as: "notificationTemplateInfo",//not working
      },
    },
    { $sort: { "notifications.createdOn": -1 } }, // Sort by createdOn field in descending order
    { $skip: (page - 1) * parseInt(itemsPerPage) },
    { $limit: parseInt(itemsPerPage) },
    { $project: { notifications: 1 } },
    //{ $unwind: "$notifications" },
 ]);


下面是我如何接收数据,注意notificationTemplate总是id

[
   {
    attachment: [],
    protocols: [ 'email', 'webapp' ],
    isRead: false,
    isDeleted: false,
    createdOn: 2023-11-03T16:46:59.372Z,
    notificationTemplate: 65451f5277306d1d2c418cd5,
    url: '/session/654524e33e894e35ac4c00b9',
    by: 63a66a814e32a254204776e8,
    sentWeb: 2023-11-03T16:50:43.769Z,
    notificationParameters: { subject: 'Networking iDea' },
    sentEmail: 2023-11-03T16:50:45.766Z,
    _id: 654524e59c36fe07f08542c5
  }
]


下面是mongodb中的示例数据。注意,每个用户将有多个通知文档

{
       "_id":{"$oid":"65461f21db7f106a02931cc2"},
       "createdDate":{"$date":{"$numberLong":"1699030019372"}},
       "user":{"$oid":"63a24f8a9d7babc0c0e51743"},
       "userEmail":"[email protected]",
       "notifications":[
        {
          "attachment":[],
          "protocols":["email","webapp"],
          "isRead":false,
          "isDeleted":false,
          "createdOn":{"$date":{"$numberLong":"1699030019372"}},
          "notificationTemplate":{"$oid":"65451f5277306d1d2c418cd5"},
          "url":"/session/654524e33e894e35ac4c00b9",
          "by":{"$oid":"63a66a814e32a254204776e8"},
          "sentWeb":{"$date":{"$numberLong":"1699030243769"}},
          "notificationParameters":{"subject":"Networking iDea"},
          "sentEmail":{"$date":{"$numberLong":"1699030245766"}},
          "_id":{"$oid":"654524e59c36fe07f08542c5"}
        }
       ]
   }


当我尝试这个,它是填充文档罚款.

const c = await Notifications.find({ user: req.params.userId }).populate(
    "notifications.notificationTemplate"
  );

qxsslcnc

qxsslcnc1#

在$lookup中,localField必须与as字段不同。
否则,它将无法正常工作。
例如,notificationTemplete字段为65451 f5277306 d1 d2 c418 cd 5,但没有_id与NotificationTemplete集合中类似数据
结果notificationTemplete字段将不会更改为Object,并保持在65451 f5277306 d1 d2 c418 cd 5中
在查询中,“localField”是“通知模板”,“as”也是“通知模板”。
换一个就能正常工作了。
例如

$lookup: {
    localField: "notificationTemplate",
    foreignField: "_id",
    from: "NotificationTemplate", 
    as: "notificationTemplateInfo",
  },

字符串
那么结果将是

[
   {
    attachment: [],
    protocols: [ 'email', 'webapp' ],
    isRead: false,
    isDeleted: false,
    createdOn: 2023-11-03T16:46:59.372Z,
    notificationTemplateInfo: 65451f5277306d1d2c418cd5,
    url: '/session/654524e33e894e35ac4c00b9',
    by: 63a66a814e32a254204776e8,
    sentWeb: 2023-11-03T16:50:43.769Z,
    notificationParameters: { subject: 'Networking iDea' },
    sentEmail: 2023-11-03T16:50:45.766Z,
    _id: 654524e59c36fe07f08542c5
  }
]


希望这个答案能对你有所帮助。
祝你好运

相关问题