[SERVER-652] modifier operations should support numerical index field names Created: 22/Feb/10 Updated: 12/Jul/16 Resolved: 03/Mar/10 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | None |
| Affects Version/s: | 1.3.2 |
| Fix Version/s: | 1.3.4 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Yun Huang Yong | Assignee: | Aaron Staple |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Participants: |
| Description |
|
> db.test.save( { _id : 1 , a : [ { x : 1 , y : 2 }, { x : 10 , y : 11 } ] }) , { "x" : 10, "y" : 11 } ] } } ) Expected { "_id" : 1, "a" : [ { "x" : 10, "y" : 11 }] } $unset on the 1st idx (2nd element) works fine though. |
| Comments |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by Aaron Staple [ 03/Mar/10 ] |
|
Performance as I measured it using perftest doesn't seem much affected. The one aspect of this change that could impact performance is substituting lexNumCmp for strcmp - we could potentially make usage of lexNumCmp more targeted, ie only in situations where we know an array modifier is in play, but not bothering with that for now. |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by auto [ 03/Mar/10 ] |
|
Author: {'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}Message: |
| Comment by Eliot Horowitz (Inactive) [ 02/Mar/10 ] |
|
Ok - I think unset should set to null. if you want to remove something, you should have to use $pull. cleaner |
| Comment by Aaron Staple [ 02/Mar/10 ] |
|
So I'm questioning a bit what I said just above. I don't know if this was completely clear above, but what I meant is that update( {a:[1,2,3]}, {$unset: {"a.1":1},$set: {"a.2":4,"a.3":5}) would produce {a:[1,4,5]}. It seems a bit more convenient to me to have the index with $set always be the index of the resulting object, so we'd get {a:[1,3,4,5]}instead. In particular I think this makes more sense when the index we're $set-ing doesn't exist initially, including situations where the $unset may or may not actually produce a change based on array length. We could have different rules depending on whether an element at that index exists initially, but that might be confusing. Just let me know what you think. |
| Comment by Eliot Horowitz (Inactive) [ 02/Mar/10 ] |
|
correct |
| Comment by Aaron Staple [ 02/Mar/10 ] |
|
I just want to make sure we're clear on the semantics of $unset with arrays. My understanding is that $unset should remove the element from the array (rather than replace with null). Remaining elements in the array will be shifted as needed. If other modifiers reference elements in the array, the references are based on indexes of elements before they are shifted as a result of $unset. |
| Comment by Eliot Horowitz (Inactive) [ 01/Mar/10 ] |
|
Yes. Should fill in with null |
| Comment by Eliot Horowitz (Inactive) [ 01/Mar/10 ] |
|
Should create an object I.e no special logic |
| Comment by Aaron Staple [ 01/Mar/10 ] |
|
Also, I'm guessing that if a $set extends the length of an array by more than one element, the extra elements that must be inserted should be set to null. |
| Comment by Aaron Staple [ 01/Mar/10 ] |
|
When we get a $set something like this: $set {"a.0":4}where a doesn't exist, should a be implicitly created as an array? Or as an object with an element having field name "0"? Inferring an array is a pain because we need to cross reference against the other modifiers. |
| Comment by Eliot Horowitz (Inactive) [ 23/Feb/10 ] |
|
yeah - i guess we should fix that. |
| Comment by Aaron Staple [ 23/Feb/10 ] |
|
There's another weird issue, which is that the mod code can only use lex sorting right now - so when an array of size > 10 is built, its elements are out of order. |
| Comment by Eliot Horowitz (Inactive) [ 23/Feb/10 ] |
|
yes - we should support this and db.f.update( {}, {$set:{"a.5":"b"}} ) in the general case |
| Comment by Aaron Staple [ 23/Feb/10 ] |
|
There doesn't seem to be any support implemented for applying mods using indexed variable names. For example, db.f.update( {}, {$set:{"a.5":"b"}} ) also fails if the length of a is less than 4. Doing $unset on any index but the last one will also cause a problem. In the instances where numeric indexes produce the correct behavior, it's mainly by chance. Do we want to support numerical indexes for all modifier operations? |