[SERVER-13509] locate mistake when using $ operation on arrays Created: 08/Apr/14  Updated: 10/Dec/14  Resolved: 08/Apr/14

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: KimShen Assignee: Thomas Rueckstiess
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Participants:

 Description   

For Example:
1,Create document which include two arrays that array "b" contain "name" attribute like "a"
db.test.insert(
{
"a":[

{"name":"a","age":"99"}

,

{"name":"b","age":"99"}

],
"b":[

{"level":"a","name":"a","age":"99"}

,

{"level":"b","name":"b","age":"99"}

]}
)

2,Update document which I want locate

{"name":"a","age":"99"}

in "a" and

{"level":"b","name":"b","age":"99"}

in "b"
db.test.update(

{"a.name":"a","b.level":"b"}

,
{"$set":{"a.$.age":"100","b.$.age":"100"}}
)

But the result is:
{"_id":ObjectId("53437c573de4c79e7ff69e91"),
"a":[

{"name":"a", "age":"99" }

,

{"age":"100","name":"b"}

],
"b":[

{"level":"a","name":"a","age":"99"}

,

{"age":"100","level":"b","name" :"b"}

]
}
Updated the "

{ "age" : "100", "name" : "b" }

" in "a" like above ...



 Comments   
Comment by KimShen [ 08/Apr/14 ]

Thanks a lot. Please close this issue.

Comment by Thomas Rueckstiess [ 08/Apr/14 ]

Hi,

Our current implementation of the positional $ operator is documented here on our page on the $ query. The two relevant paragraphs are:

the positional $ operator acts as a placeholder for the first element that matches the query document, and

The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.

The $ sign is the index of the match in the first array, and it is a placeholder for a single value. So what you are trying to achieve is currently not possible with a single update and would require two updates, or rewriting the a and b arrays entirely as part of the update.

A similar feature request to allow the positional operator for nested arrays is SERVER-831.

Thanks,
Thomas

Comment by KimShen [ 08/Apr/14 ]

Add Example:
> db.test.findOne()
{
"_id" : ObjectId("53438e4768b6db4ddf4f3ce3"),
"a" : [

{ "name" : "a", "age" : "aa" }

,

{ "name" : "b", "age" : "ab" }

],
"b" : [

{ "level" : "a", "age" : "ba" }

,

{ "level" : "b", "age" : "bb" }

]
}

Then update:
db.test.update(

{"a.name":"a","b.level":"b"}

,{"$set":{"a.$.age":"ax"}})

And result:
> db.test.findOne()
{
"_id" : ObjectId("53438e4768b6db4ddf4f3ce3"),
"a" : [

{ "name" : "a", "age" : "aa" }

,

{ "name" : "b", "age" : "ax" }

],
"b" : [

{ "level" : "a", "age" : "ba" }

,

{ "level" : "b", "age" : "bb" }

]
}

If want locate document using two query in two arrays then update , that's mistake

Comment by KimShen [ 08/Apr/14 ]

May be query for "a" locate "array index 1" and query for "b" locate "array index 2", that final location using "b" ?

Generated at Thu Feb 08 03:31:56 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.