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

] })
> db.test.find()
{ "_id" : 1, "a" : [

{ "x" : 1, "y" : 2 }

,

{ "x" : 10, "y" : 11 }

] }
> db.test.update( {}, { $unset:

{"a.0":1}

} )
> db.test.find()

{ "_id" : 1, "a" : [ null ] }

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: SERVER-652 more complete test
http://github.com/mongodb/mongo/commit/c8c070f781cc79da83a9d87ea92155af6da5783d

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: SERVER-652 add const
http://github.com/mongodb/mongo/commit/2691d5bde9a9f5b784a0223d3b262edc4e9af5cc

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 update test
http://github.com/mongodb/mongo/commit/e9c6ec66ff8903d16fb026a1ce5f1796b07e285b

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 unset/array sets value to null, which makes more sense
http://github.com/mongodb/mongo/commit/4461c46f3f34a8a5c4d24cfb0485e09014135af5

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 checkpoint
http://github.com/mongodb/mongo/commit/6546599f73b490d8f8ad4bb54a27ac99e809e5fb

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 simplify field name upper limit check, guard against setting string fields in arrays
http://github.com/mongodb/mongo/commit/246109cc18b72e39e92bc1c4e4a9a28e70379cb9

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 process array elements in correct order
http://github.com/mongodb/mongo/commit/bbbe0aaf31d4b0a536768a58245a07d42c8eb190

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 comment
http://github.com/mongodb/mongo/commit/df8fb47a4c70a99ae34b4a58a79490781b1bde23

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 basic support for set with indexed elements
http://github.com/mongodb/mongo/commit/6a95b558e12a9a13f3ca9dcdd6590d9d30f7990d

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 forgot test
http://github.com/mongodb/mongo/commit/584310b50c09860747823c16ffe6f3507ae0c1ae

Comment by auto [ 03/Mar/10 ]

Author:

{'login': 'astaple', 'name': 'Aaron', 'email': 'aaron@10gen.com'}

Message: SERVER-652 basic array index unset support
http://github.com/mongodb/mongo/commit/bccf8f4113a8864514832306448e67b271b93253

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.
i think its not usually an issue since many drivers use the key names as where it should goes, not the order.
we should still fix though.
probably deserves a new case

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?

Generated at Thu Feb 08 02:54:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.