Home > Software design >  What causes Mongoose `updateMany` to return `{ acknowledged: false }`
What causes Mongoose `updateMany` to return `{ acknowledged: false }`

Time:12-04

I'm trying to set up notifications for an Express app using MongoDB.

I have an API endpoint where I $push a user's id to the readBy field in MongoDB to "mark" it as read after retrieving a user's notifications. When I make a request to this endpoint, it returns 200 and their notifications, but it isn't making any updates to the notification document in MongoDB. console.loging the query response in the callback gave me { acknowledged: false }. According to the Mongoose docs, acknowledged is a Boolean indicating everything went smoothly, but information about what acknowledged is and at which point in the query/write process caused it to occur was sparse. Since it didn't return any errors I couldn't find a way to troubleshoot it.

Would someone be able to shed some light on what exactly acknowledged: false is and in what typically causes it, and why it doesn't throw an error.

Model:

const notificationSchema = new Schema({
  timestamp: {
    type: Date,
    required: true
  },
  type: {
    type: String,
    required: true,
    enum: [
      'newCustomer',
      'contractSigned',
      'invoicePaid',
      'warrantyExp',
      'assignedProject'
    ]
  },
  recipients: [{
    type: Schema.Types.ObjectId,
    ref: 'Employee',
    required: true,
  }],
  customer: {
    type: Schema.Types.ObjectId,
    ref: 'Customer',
    required: true,
  },
  readBy: [{
    type: String
  }],
  uuid: {
    type: String,
    default: uuid.v4,
    immutable: true,
    required: true,
  },
  company: {
    type: Schema.Types.ObjectId, ref: 'Company'
  }
});

Route:

router.get("/notification/all", withAuth, async (req, res) => {
  const FOURTEEN_DAYS = new Date().setDate(new Date().getDate()   14);
  try {
    const { uuid, userId } = req.loggedInUser;

    // Fetch notifications that have the user as a recipient.
    Notification.find({
      recipients: userId,
    })
      .populate("customer")
      .exec((err, notifs) => {
        if (err)
          return res.status(500).json({
            success: false,
            message: "Error: Failed to retrieve notifications.",
          });

        const result = [];
        const notifIds = [];

        for (const notif of notifs) {
          // Filter notif
          result.push({
            timestamp: notif.timestamp,
            customer: notif.customer,
            type: notif.type,
            read: notif.readBy.includes(uuid),
          });
          // Add the user as read
          notifIds.push(notif.uuid);
        }

        console.log(notifIds);

        /* THIS RETURNS ACKNOWLEDGED: FALSE */         
        // Write to DB that user has read these notifications
        Notification.updateMany(
          { uuid: { $in: notifIds } },
          { $push: { readBy: uuid } },
          (err, resultUpdate) => {
            if (err)
              return res.status(500).json({
                success: false,
                message:
                  "Error: Failed to add check off notifications as read.",
              });

            console.log(resultUpdate);

            // Delete notifications past 14 days and has been read by all recipients
            Notification.deleteMany(
              {
                timestamp: { $gte: FOURTEEN_DAYS },
                $expr: {
                  $eq: [{ $size: "$readBy" }, { $size: "$recipients" }],
                },
              },
              (err) => {
                if (err)
                  return res.status(500).json({
                    success: false,
                    message: "Error: Failed to delete old notifications.",
                  });

                return res.status(200).json({
                  success: true,
                  notifications: result,
                  message: "Fetched notifications",
                });
              }
            );
          }
        );
      });
  } catch (err) {
    res.status(500).json({ success: false, message: err.toString() });
  }
});

CodePudding user response:

From the docs:

The method returns a document that contains:

  • A boolean acknowledged as true if the operation ran with write concern or false if write concern was disabled
  • matchedCount containing the number of matched documents
  • modifiedCount containing the number of modified documents
  • upsertedId containing the _id for the upserted document

CodePudding user response:

So it turns out that this issue was unrelated to write concern. acknowledged: false was being returned because the value we were trying to $push was undefined. So essentially Mongoose was refusing to write undefined values, but doesn't throw an error for the input value being undefined. Putting this here in case someone else runs into this issue.

  • Related