I know this has been asked a lot, but I can't get it done via other answers. So could someone help me find the mongoose equivalent of this mongosh query? I have this data:
{
data: [
{
x: 1,
y: 1
},
{
x: 11,
y: 11
},
{
x: 111,
y: 111
}
]
}
In order to update a nested object inside an array, I do this in Mongo SH and it works:
*.updateOne({_id: 'ID_HERE', "data.x": 1}, {$set: {"data.$": { x: 2, y: 2 }} })
How would I do this in mongoose? This is how I have ran it
const result = await Positions.updateOne(
{ _id: collectionId, "data.x": 1 },
{
$set: {
"data.$": { x: 2, y: 2 },
},
}
);
Response from *.updateOne:
{
"acknowledged": false
}
Response from *.findOneAndUpdate simply returns the same data untouched
Though the update does not happen. Using mongoose v6.0.6
I believe the issue is with the $
position selector. If I change $set to update "data" directly instead of "data.$", it works, but of course, it is not what I want as it replaces the entire data array.
Thank you in advance.
EDIT:
Thanks to Joe's answer, I found the problem.
The problem was actually in the Schema.
data was set as an object instead of array of objects
So I updated the Schema from data: {x: Number, y: Number}
to data:[{x: Number, y: Number}]
Thanks to everyone who contributed!
CodePudding user response:
This is not a full solution, but it does provide some relevant data that will help find one.
I made a quick test for the code you gave:
const mongoose = require("mongoose");
async function main() {
await mongoose.connect("mongodb://localhost:27017/");
const Arrtest = mongoose.model("arrtest",new mongoose.Schema({data:[{}]}));
const newdoc = await Arrtest.create({
data: [
{
x: 1,
y: 1
},
{
x: 11,
y: 11
},
{
x: 111,
y: 111
}
]
});
console.log("Mongoose version:", mongoose.version);
console.log("before:",await Arrtest.findOne({_id:newdoc._id}));
const result = await Arrtest.updateOne(
{"_id":newdoc._id, "data.x":1},
{$set:{
"data.$":{x:2,y:2}
}}
);
console.log("result:",result);
console.log("after:",await Arrtest.findOne({_id:newdoc._id}));
process.exit(0);
}
main();
The result of running that was:
Mongoose version: 6.0.8
before: {
_id: new ObjectId("615a995ea3ae207cde4c6984"),
data: [ { x: 1, y: 1 }, { x: 11, y: 11 }, { x: 111, y: 111 } ],
__v: 0
}
result: {
acknowledged: true,
modifiedCount: 1,
upsertedId: null,
upsertedCount: 0,
matchedCount: 1
}
after: {
_id: new ObjectId("615a995ea3ae207cde4c6984"),
data: [ { x: 2, y: 2 }, { x: 11, y: 11 }, { x: 111, y: 111 } ],
__v: 0
}
This seems to be doing exactly what you wanted, so the problem does not appear to be in the update expression.
Perhaps there is a validation problem, or something mismatching with the Positions
model or schema?
CodePudding user response:
can you try :
await Positions.updateOne(
{ _id: collectionId, "data.x": 1 },
{
"data.$.x":2 ,
"data.$.y":2 ,
}
);