I can't seem to get this mongoose $pull
operation to work at all. I have tried many solutions, but would ultimately like to use an atomic operation to achieve this as that is the design pattern in the rest of my code.
In my List
schema, I have an array of Item
objects. Each Item
object has an array of Notes
which are all string values. Creating, Reading, and Updating these Notes
arrays has been no issue. But I can't seem to get the Delete functionality to work.
Schemas:
List
const listSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "Users"
},
name: {
type: String
},
items: {
type: Array,
default: [itemSchema]
}
});
Item
const itemsSchema = {
item: String,
style: String,
moved: Boolean,
notes: Array
};
Sample Document:
_id: 6186940ce10fbd7cec9fb01f
items: Array
0: Object
notes: Array
0: "Updated again x2"
1: "Test one to delete edit"
2: "New one"
_id: 6186d98dcef2ae43605becc4
item: "Test 1"
style: ""
moved: false
1: Object
notes: Array
_id: 6186d98fcef2ae43605becc5
item: "Test 2"
style: ""
moved: false
2: Object
notes: Array
_id: 6186d991cef2ae43605becc6
item: "Test 3"
style: ""
moved: false
3: Object
notes: Array
0: "Add from none"
1: "typing a really long sentence here to see what happens when I get to t..."
2: "Test"
_id: 6186d994cef2ae43605becc7
item: "Test 4"
style: ""
moved: false
user: 611083d8baed4458d8dcd273
name: "Nov-06-2021"
__v: 0
Methods:
Create
List.findOneAndUpdate(
{ "user": req.user.id, "name": list, "items._id": ObjectId(id) },
{ "$push": { "items.$.notes": newNote } },
{ new: true },
(err, newList) => {}
)
Update
List.findOneAndUpdate(
{ "user": req.user.id, "name": list, "items._id": ObjectId(id) },
{ "$set": { "items.$.notes.$[note]": newNoteText } },
{
arrayFilters: [{"note": note}],
new: true
},
(err, newList) => {}
)
Delete (not working)
List.findOneAndUpdate(
{ "user": req.user.id, "name": list, "items._id": ObjectId(id) },
{ "$pull": { "items.$.notes.$[note]": note } },
{
arrayFilters: [{"note": note}],
new: true
},
(err, newList) => {}
)
The current Delete code block is close to what I'd like my solution to look like. By all rights, and everything I've read, it should already work. Can anyone show me what will work, and possibly why this isn't currently working?
I have tried many solutions including using $in
, $[]
, $elemMatch
, and a bunch more outside the box solutions. I don't see why $push
and $set
work without issue, but $pull
is deciding to do nothing.
The current response I get from MongoDb with this operation doesn't include an error message, but the returned newList
is a null
value, and no change is reflected in my DB. I am currently on the latest version of mongoose: 5.13.13
.
CodePudding user response:
The solution to this was to remove the $[note]
from my operator as $pull
requires an array to operate on, not the array object.
I definitely tried that before, before there was an issue with my request body that was coming from the front end. I wasn't using the correct syntax for an axios.delete
, however, and that was my main issue.
Solution
List.findOneAndUpdate(
{ "user": req.user.id, "name": list, "items._id": ObjectId(id) },
{ "$pull": { "items.$.notes": note } },
{ new: true },
(err, newList) => {}
)
I removed $[note]
as a variable because $pull
operates on the entire notes
array. Therefore, I no longer need the arrayFilters
because it is already looking for the note
variable.