0

Currently my User model looks like:

{
  _id: 'SomeId'
  firstName: 'John',
  lastName: 'Cena',
  books: [
  { 
   _id: 'xyz',
    title: 'a', 
    author:'b', 
    ratings:[
      {source:'source1', value:"8"},
      {source:'source2', value:"9"}] 
  },

  {
    _id: 'abc',
    title: 'c', 
    author:'d',
    ratings:[
      {source:'source3', value:"7"},
      {source:'source4', value:"5"}] 
   }
 ]
}

After making an findOneAndUpdate query to update rating=>value of 1st book object(_id: "xyz") from 8 to 10 for a given source(say "source1"):

  let up={
     'books.$[book].ratings.$[rating].value':10
       }
  let filter={
      new:true,
      'books.rating':1,         //I just want rating array of updated objects in it
     arrayFilters:[
        { 'book._id':'xyz'},   
        { 'rating.source': 'source1'}
        ]
    }
  User.findOneAndUpdate({'_id':'userId','books._id':'xyz'},up,filter).select('books.rating').exec((err,doc)=> {
  if (err) throw err;
  console.log(doc);
  }

My code updates the books=>rating=>value correctly but I can't get that updated rating of that book. This gives me rating of all books with both updated and non updated values in it. Looks like:-

{
  books: [{ ratings:[{source:'source1', value:"10"},{source:'source2', value:"9"}] },
          { ratings:[{source:'source3', value:"7"},{source:'source4', value:"5"}] }]
} 

I think the data of 2nd book shouldn't be there at all according to my code. I expect the follwing output:

{
  books: [{ ratings:[{source:'source1', value:"10"}] }    
}

Please help me to write findOneAndUpdate query correctly!

3
  • So you only want { books: [{ ratings:[{source:'source1', value:"10"}] } } or the entire Document with only that rating object? Commented Oct 14, 2019 at 19:23
  • { books: [{ ratings:[{source:'source1', value:"10"}] } } only! Commented Oct 15, 2019 at 7:27
  • See my response below Commented Oct 15, 2019 at 15:49

1 Answer 1

2

you can use array.find() like this:

const updatebookSource = (sourceId, userId, bookId) => {
  User.findOneAndUpdate({ _id: userId, "books._id": bookId }, up, filter).exec(
    (err, doc) => {
      if (err) throw err;
      let res = doc.books[0].ratings.find(rating => {
        return rating.source === sourceId;
      });

      console.log(JSON.stringify(res, null, 1));
    }
  );
};

This returns the updated object. Let me know if it works.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.