Search code examples
mongodbmongoosemongoose-schema

How to update with mongoose


I have this record

{
    "_id" : ObjectId("5dfdff479ad032cbbc673507"),
    "selection" : [ 
        {
            "highlights" : "test",
            "comment" : "CHANGE THIS",
            "el" : "body:nth-child(2)>div:nth-child(2)#root>div.App>p:nth-child(1)"
        }, 
        {
            "highlights" : "Barrett’s lyrical prose opens with a clever and tender solution",
            "comment" : "",
            "el" : "body:nth-child(2)>div:nth-child(2)#root>div.App>p:nth-child(2)"
        }
    ],
    "category" : [],
    "status" : "",
    "url" : "http://localhost:3000/theone",
    "title" : "React App test",
    "__v" : 4
}

And I want to update the comment. I have tried to use update and findOneAndUpdate and nothing is working. Here is my attempt

WebHighlight.findOneAndUpdate(
  {
    _id: req.params.highlight,
    "selection.highlights": "test"
  },
  { "selection.$.comment": "yourValue" }
);

That req.params.highlight is the id (I even hardcoded it)

I also tried this

WebHighlight.findById(req.params.highlight, (err, book) => {
  var test = [...book.selection];
  test[0].comment = "somethibf"
  book.save();
  res.json(book);
});

And nothing is working.

This is the model

const webhighlightsModel = new Schema({
  selection: { type: Array, default: "" },
  category: { type: Array, default: [] },
  title: { type: String },
  url: { type: String },
  status: { type: String, default: "" }
});

Solution

  • Actually your code seems to work, but findOneAndUpdate returns the old document if you don't give {new: true} option.

    I think for this reason, you think the update wasn't successfull, but if you check your collection, you will see the update.

    WebHighlight.findOneAndUpdate(
      {
        _id: req.params.highlight,
        "selection.highlights": "test"
      },
      { "selection.$.comment": "yourValue" },
      { new: true }
    )
      .then(doc => res.send(doc))
      .catch(err => res.status(500).send(err));
    

    Also I think it would be better if selection had a sub schema like this:

    const mongoose = require("mongoose");
    
    const schema = new mongoose.Schema({
      selection: [
        new mongoose.Schema({
          highlights: String,
          comment: String,
          el: String
        })
      ],
      category: { type: Array, default: [] },
      title: { type: String },
      url: { type: String },
      status: { type: String, default: "" }
    });
    
    module.exports = mongoose.model("WebHighlight", schema);
    

    So with this every selection would an _id field, and it would be better to update with this _id.