-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Saving document with projected sub document modifies the wrong sub document #1334
Comments
Mongoose is not a good fit for this use case because it was designed such that Work-around:
You may also consider using lean() in combination with |
I'm thinking returning an error to the save callback when this is attempted is the "right thing" in this circumstance. |
Are you going to redesign something in mongoose in future to fit more such cases? Mongoose is great but sometimes it forces to query exessive data from db. ( |
Not in the foreseeable future. If mongodb adds some new feature we'll revisit. |
It should also be noted that this doesn't work for queries where only the matching subdocument is returned. User.findOne(
{'orders._id': orderId},
{'orders.$': 1},
done
); Changes made to |
Related to #2031 |
This might actually be doable using $(update) since version 2.6 of MongoDB: https://docs.mongodb.org/v2.6/reference/operator/update/positional/ |
@geloescht can you provide a code sample that demonstrates what you're looking to do? |
I am developing a solution for content localization. Basically, instead of modifying a translatable document property directly, I use a virtual that modifies an entry inside an array with localized data. To save memory and computing power for documents with a lot of translations I use projection to only retrieve localized data for a single language. This is all wired up using mongoose middleware. apps.findOne(
{
_id: ObjectId("567452bae5b25d6e6c1a0f7e")
},
{
localization: { '$elemMatch': { language: 'de' } }, dummy_: 0
}).exec(function(err, app)
{
//a real gentleman woud handle this error
app.localization[0].name = "Neuer Name";
app.save(); //throws DivergentArrayError
//this is the query that saves the way I want
apps.findOneAndUpdate(
{
_id: ObjectId("567452bae5b25d6e6c1a0f7e"),
localization: { '$elemMatch': { language: 'de' } }
},
{
$set: { 'localization.$.name' : "Neuer Name" }
}).exec(//...
}); |
Yeah supporting that behavior in |
Thanks for looking into this! |
…n saving document
@geloescht a thousand thanks to you. I've spent the last 2 hours trying to code a workaround, then 1 more trying to find a solution until I stumbled upon yours, great work! I guess besides the '.$' there is still no other support for elemMatch and saving? |
@filipetedim My PR adds support for saving fields selected via |
@geloescht Yeah I'm using the '$.' for the moment - tbh I thought that was your code. So how will I call your function to use it? Or will I just hit "save()" and it will work? Again, nice work finding the $. solution and implementing a new feature on the PR. |
Yeah upon closer inspection OP's issue was fixed in 4.5.0 with #4053 |
Hi,
when retrieving a document using findOne while limiting the result of an array of sub documents via an $elemMatch projection, the wrong array element will get modified in the database when saving the document back.
Please see the following test case:
https://gist.github.com/4711139
Which produced the following debug output:
Notice up the update command sets 'subDocs.0.someValue' instead of 'subDocs.2.someValue'. I assume this is because an array with only a single element was returned due to the projection.
We have been relying on mongoose's ability to selectively update parts of large documents including many subdocuments depending on what data had been modified. Without the ability to use projection, the document retrieval kills our performance as node will spend a bulk of its time parsing the bson data. See also the following issue for a similar issue that we've encountered:
#1303
Thanks!
This is using mongoose 3.5.4
The text was updated successfully, but these errors were encountered: