[SERVER-36009] $min, $max field update operators from another field Created: 08/Jul/18 Updated: 16/Nov/21 Resolved: 16/Aug/18 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Marcos Fernándex | Assignee: | Asya Kamsky |
| Resolution: | Incomplete | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Participants: |
| Description |
|
I've pass the last hours searching for a realiable way to keep a minimun field value up to date. For example, you have: { minAll: [1,2,3,4], min: 1 }For this current case, Its possible to have an index on 'minAll' and query a '$min' operator under aggregate, but (1) the index will grow more so Its more memory expensive and (2) having it precalculated in another field you can get some performance improvements. The basic idea is: update({"_id":"test"}, { "$pull":\{"minAll":1}, When you remove or add an element, would be great to be able to update another field based on the new collection this field currently has. Or simply re-index all documents again: update({},{ Currently you can do it this way: var elem = findAndModify({"_id":"test"},{"$pull":{"minAll":1}}); I have no problem doing 2 updates, the main problem from my pov is that this is not atomic, so if you have bad luck, under heavy load, in the microseconds you use to calculate 'nmin' the 'minAll' field could have changed and updated 'min' in parallel, so you are basically overwriting the field with old value. This is similar to https://jira.mongodb.org/browse/SERVER-1534?focusedCommentId=322573&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-322573 . With current behaviour you can easily keep up to date the max value of an array field modified by $push, but you have no chance to update max if you use a $pull and removed the top value. Thanks! |
| Comments |
| Comment by Marcos Fernándex [ 26/Aug/18 ] |
|
Fair enough Thanks |
| Comment by Asya Kamsky [ 26/Aug/18 ] |
|
> javascript fix only We do not plan to implement this in any driver language - this would use existing server operators/expressions exactly as you suggest in the comment. |
| Comment by Marcos Fernándex [ 16/Aug/18 ] |
|
Hi, sorry, missed last message. I'm not sure if this will be addressed completely by { $set : { "priority" : min(old.priority, 3) }} Yes, a similar approach could workaround this problem, but I think it's a javascript fix only. I use mongodb in several languages but mainly in php, there is no way I could think to translate that to a findAndModify or update valid query in php for example, so could cause more headaches to port. My proposal was more simple than that. Mongo already gives you min value of an array field when you use $min under an aggregate, so there is a behaviour that everybody knows. I just comment on extending this same behaviour to the findAndModify/update $set query, just for language consistence: {$set:{"newfield":{$min:"$oldfield"}}}
Maybe with {$set:{"newfield":{$min:["$oldfield",3]}}} Using mongo native $min instead of Math.min could be ok, but imho it's incomplete, just because aggregate allows the 2 operations. I opened this bug with lowest priority because it's not a blocker or something important, just to remind the mongo guys that the $min and $max operators should has its place in findAndModify/update in the end and should behave like they do on aggregate. Thanks |
| Comment by Asya Kamsky [ 16/Aug/18 ] |
|
We think this would be addressed by |
| Comment by Ramon Fernandez Marina [ 16/Jul/18 ] |
|
sombra2eternity, would something like |