[DOCS-13323] Investigate changes in SERVER-40687: Positional projection ($) only considers first path component when comparing to query document Created: 02/Jan/20  Updated: 13/Nov/23  Resolved: 25/Jun/20

Status: Closed
Project: Documentation
Component/s: manual
Affects Version/s: None
Fix Version/s: 4.3.3, Server_Docs_20231030, Server_Docs_20231106, Server_Docs_20231105, Server_Docs_20231113

Type: Task Priority: Major - P3
Reporter: Backlog - Core Eng Program Management Team Assignee: Jeffrey Allen
Resolution: Fixed Votes: 0
Labels: docs-query
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Documented
documents SERVER-40687 Positional projection ($) only consid... Closed
Participants:
Days since reply: 3 years, 32 weeks, 6 days ago
Epic Link: DOCS: 4.4 Server Release Work

 Description   

Description

Downstream Change Summary

In 4.3 users will be allowed to apply the positional projection to fields that are not part of the query document.

For example db.c.find(

Unknown macro: {a}

,

Unknown macro: {b.$}

).

This was illegal in 4.2 (the positional projection had to be on a field used in the filter).

This brings the behavior of positional projection and positional update closer together.

Description of Linked Ticket

Using a non-matching subfield (e.g., query: fieldExists.something: 1 projection: fieldExists.fieldDoesntExist.$) with the $ projection operator does not return the Positional projection 'fieldExists.fieldDoesntExist.$' does not match the query document error.
 
Given the document:

{
	"_id" : ObjectId("5cb8ab2f20926051ca9e2cd7"),
	"AOE" : [
		{
			"areaOfExpertise" : "aoe1",
			"subAOE" : []
		},
		{
			"areaOfExpertise" : "aoe2",
			"subAOE" : []
		}
	],
	"poolName" : "newpool",
	"__v" : 0
}

The {"AOE.doesntExist.$":1} projection is treated the same as the correct {"AOE.$":1} projection:

> db.proj.find({ poolName: "newpool", "AOE.areaOfExpertise": "aoe1" },{"AOE.doesntExist.$":1}).pretty()
{
	"_id" : ObjectId("5cb8ab2f20926051ca9e2cd7"),
	"AOE" : [
		{
			"areaOfExpertise" : "aoe1",
			"subAOE" : []
		}
	]
}
> db.proj.find({ poolName: "newpool", "AOE.areaOfExpertise": "aoe1" },{"AOE.$":1}).pretty()
{
	"_id" : ObjectId("5cb8ab2f20926051ca9e2cd7"),
	"AOE" : [
		{
			"areaOfExpertise" : "aoe1",
			"subAOE" : []
		}
	]
}

Scope of changes

Impact to Other Docs

MVP (Work and Date)

Resources (Scope or Design Docs, Invision, etc.)



 Comments   
Comment by Githook User [ 25/Jun/20 ]

Author:

{'name': 'jeff-allen-mongo', 'email': 'jeffrey.allen@10gen.com', 'username': 'jeff-allen-mongo'}

Message: (DOCS-13323): $ positional operator improvements
Branch: master
https://github.com/mongodb/docs/commit/d725af9eccd7aad6d34d466e813ff089ddddc1ba

Comment by Jeffrey Allen [ 10/Jun/20 ]

Thanks ian.boros! This clears things up.

Comment by Ian Boros [ 10/Jun/20 ]

Hi jeffrey.allen,

You have the right idea. In general this new behavior is only really useful for cases where you have "parallel arrays". The following now works in 4.4, but did not in 4.2.

> db.c.insert({a: [1,2,3], b: ["one", "two", "three"]})
> db.c.find({a: 1}, {"b.$": 1})
{ "_id" : ObjectId("..."), "b" : [ "one" ] }

In 4.2, you could do this when the field we're filtering on and the field we're projecting had a common parent. For example:

> db.c.insert({x: {a: [1,2,3], b: ["one", "two", "three"]}})
> db.c.find({"x.a": 1}, {"x.b.$": 1})
{ "_id" : ObjectId("..."), "x" : { "b" : [ "one" ] } }

So, 4.4 expanded this to work on top-level fields as well. In general this is only useful when the the field with positional projection is an array and the field with the filter is an array.

Generated at Thu Feb 08 08:07:29 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.