[SERVER-4102] Add $nop operation to modifier Created: 19/Oct/11 Updated: 07/Mar/14 Resolved: 20/Oct/11 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Usability, Write Ops |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Richard Miller-Smith | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 0 |
| Labels: | update | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Participants: |
| Description |
|
Although it can be worked around, it can be problematic that when an empty modifier object is used with findAndModify it removes all properties of the document. We suggest adding a no-op modifier operation, $nop, which makes no change to the document. This can therefore be added to all modifier operations and will ensure that previously empty ones will not wipe out the document: Usage: |
| Comments |
| Comment by Scott Hernandez (Inactive) [ 20/Oct/11 ] |
|
In many drivers there is a findOne which takes a field restriction and a sort. This is really not an issue for the server but one of your client (driver). Please file an issue with the node.js driver if you want a findOne method which takes those parameters, assuming there isn't one, which would actually surprise me... findOne is shorthand for this: findOne(args): The same behavior exists for update. I would suggest filing a bug for findAndModify with an empty set of updateOperations not generating an error but really, that again should be checked by the driver before it ever sends it to the server. |
| Comment by Richard Miller-Smith [ 20/Oct/11 ] |
|
The problem with using findOne() is that it is a much less powerful beast than findAndModify, you can't give it a fields parameter nor a sort order (let alone options like 'upsert'). This means that doing this: var result1, 2 ; , sort:[["aProperty",1]], update: {something: "toSet"}, fields: {aProperty: 1}) ) then result1 and result2 could be completely different documents, and at the very least would have different fields. Therefore, you can't use findOne() as a safe replacement for findAndModify. My biggest concern, spurred on by the bugs we have had, is that when you get it wrong and accidently call findAndModify with an empty object it does such a dangerous thing - wiping out the object. Which basically means that anywhere a modifier is created (that could possibly be empty) then you cannot just use findAndModify, you have to remember to use an arrangement at least as complex as yours above. Perhaps a $nop isn't the best solution - maybe just another option to findAndModify would fix it. But I do think this is a real issue that bites and surprises people when they suddenly discover objects have been wiped out, and it seems strange to have such a powerful call as findAndModify and then need to wrap it with extra code in order to catch corner cases. |
| Comment by Scott Hernandez (Inactive) [ 19/Oct/11 ] |
|
I still don't get the issue, or need. Here is the logic in psudocode: var mods = ... If you have no mods, don't do a findAndModify. I don't understand what this has to do with sorting, or two calls. |
| Comment by Richard Miller-Smith [ 19/Oct/11 ] |
|
Indeed, and that is what we are currently doing. However, as we are using JavaScript (in node.js) in order to get the correct object back (due to sorting etc) we have to do two async calls instead of one: a find() and then read the first item from the cursor. It was just a thought that having a mechanism (such as this) that could mark a modifier as a no-op would make usage a bit easier - this problem has reared its head a few times now on our project. |
| Comment by Scott Hernandez (Inactive) [ 19/Oct/11 ] |
|
If you don't need to modify the document, just do a query. |