Reputation: 235
I am trying to update the object inside the document
Document: Cats
{
"_id": "5e5cb512e90bd40017385305",
"type": "cat"
"history": [
{
"id": "randomID",
"content": "xyz",
},
{
"id": "randomID2",
"content": "abc",
}
]
}
Code to select and update the object inside the history array:
const editHistory = async (_, { input }, ctx) => {
let query = { _id: input.catId, "history.id": input.historyId };
let update = { $set: { "history.$": input.history } };
let options = {
new: true,
fields: { history: { $elemMatch: { id: "randomID" } } }
};
let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);
return cat;
};
Input has following values
input: {
catId: "5e5cb512e90bd40017385305",
historyId: "randomID",
history: {
id: "randomID",
content: "new content"
}}
I tried using Projection, I used select changed it to field, found in mongoose documentation. I still couldn't update the values. Is there anything wrong with the way i am querying or selecting the subfield.
Upvotes: 0
Views: 173
Reputation: 235
Found the Solution for it by going through more detail of the operator($set) and option(new, fields).
Question:
const editHistory = async (_, { input }, ctx) => {
let query = { _id: input.catId, "history.id": input.historyId };
let update = { $set: { "history.$": input.history } };
let options = {
// using new option would return the new document
new: true,
/* using fields option would select the based on the given key, but using new:
true with fields will throw error: 'cannot use a positional projection and
return the new document'
*/
fields: { history: { $elemMatch: { id: "randomID" } } }
};
let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);
return cat;
};
This post below answers that question for *error: 'cannot use a positional projection and return the new document'.
https://stackoverflow.com/a/46064082/5492398
Final Solution:
const editHistory = async (_, { input }, ctx) => {
let query = { _id: input.catId, "history.id": input.historyId };
let update = { $set: { "history.$": input.history } };
let options = {
new: true
};
let cat = await ctx.models.cats.findOneAndUpdate(query, update, options);
return cat;
};
Removing field option, since I don't need the unmodified selection before atomic modification, solves the question.
Upvotes: 1