[SERVER-16409] Updates against paths composed with array index notation and positional operator can insert an embedded document Created: 03/Dec/14  Updated: 03/Dec/14  Resolved: 03/Dec/14

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: 2.6.4
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Jon Hyman Assignee: Ramon Fernandez Marina
Resolution: Duplicate Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-14886 Updates against paths composed with a... Closed
duplicates SERVER-14662 Positional projection queries (and po... Closed
Related
related to SERVER-14886 Updates against paths composed with a... Closed
Operating System: ALL
Participants:

 Description   

Not sure if this is related to https://jira.mongodb.org/browse/SERVER-14886 or not, but updates to an embedded document in an array can cause an insertion to happen in 2.6.4 but the correct update in 2.4.10.

db.test.insert({
  root: [
    {
      _id: "A",
      children: [
        {_id: "C", name: "Alice"}
      ]
    },
    {
      _id: "B",
      children: [
        {_id: "D", name: "Bob"}
      ]
    }
  ]
})

To update Bob's name to Carol, I can issue:

db.test.update({"root._id": "B", "root.1.children._id": "D"}, {$set: {"root.1.children.$.name": "Carol"}})

In 2.4, this update's Bob's name to Carol. In 2.6.4, this INSERTS Carol:

mongos> db.test.find({}).pretty()
{
	"_id" : ObjectId("547f72c1e52e8693ed137ad6"),
	"root" : [
		{
			"_id" : "A",
			"children" : [
				{
					"_id" : "C",
					"name" : "Alice"
				}
			]
		},
		{
			"_id" : "B",
			"children" : [
				{
					"_id" : "D",
					"name" : "Bob"
				},
				{
					"name" : "Carol"
				}
			]
		}
	]
}

Note that if you drop the

{"root._id": "B"}

part of the clause in the update, you get the 'The positional operator did not find the match needed from the query' error from SERVER-14886.



 Comments   
Comment by Ramon Fernandez Marina [ 03/Dec/14 ]

Hi jonhyman, thanks for your report. There are two separate issues here, and one of them (the "positional operator did not find the match" error message) is indeed SERVER-14886 which was recently fixed for 2.6.6. A 2.6.6-rc0 release candidate was published recently (scheduled for the coming weeks).

The other behavior (using the "wrong" value for the positional operator) was reported in SERVER-14837, and you can see a detailed explanation in this comment. In summary, the value of the positional operator in 2.4 was ambiguous and 2.6 corrected that. This is easy to test by swapping the order of the predicates in the query part of your update operation:

db.test.update({"root.1.children._id": "D", "root._id": "B"}, {$set: {"root.1.children.$.name": "Carol"}})

This has the effect of adding "Carol" to the subdocument with _id "B".

You can find more details in the documentation of the positional operator. Note also that SERVER-14662 was opened to see how can things be improved in this area, so feel free to tune into SERVER-14662 and vote for it if you're interested.

Regards,
Ramón.

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