[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}

,
        "$set":{"min":{"$min":"$minAll"}} //should be 2 now
    });

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({},{
        "$set":{"min":{"$min":"$minAll"}}
    });

Currently you can do it this way:

   var elem = findAndModify({"_id":"test"},{"$pull":{"minAll":1}});
   var nmin = Math.min(elem.minAll);
   /* Posible other delays */
   findAndModify({"_id":"test"},{"$set":{"min":nmin}});

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 SERVER-1765.
In the description of that report there is the next example:

{ $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 SERVER-1765 you could make something like:

{$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 SERVER-1765

Comment by Ramon Fernandez Marina [ 16/Jul/18 ]

sombra2eternity, would something like SERVER-1765 address your needs?

Generated at Thu Feb 08 04:41:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.