[SERVER-15013] Projection of field in a concrete array element (dot notation) returns element as empty object Created: 24/Aug/14  Updated: 28/Aug/14  Resolved: 28/Aug/14

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

Type: Bug Priority: Major - P3
Reporter: Thomas Zahn Assignee: Ramon Fernandez Marina
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to SERVER-15083 Allow projection of specific array el... Closed
Operating System: ALL
Steps To Reproduce:

> db.projection_test.insert({ "some_field" : "some_value1", "my_array" : [ { "num_field" : 100, "s_field" : "aaa" }, { "num_field" : 100, "s_field" : "bbb" } ] })
WriteResult({ "nInserted" : 1 })
> db.projection_test.insert({ "some_field" : "some_value2", "my_array" : [ { "num_field" : 500, "s_field" : "aaa" }, { "num_field" : 100, "s_field" : "bbb" } ] })
WriteResult({ "nInserted" : 1 })
> db.projection_test.insert({ "some_field" : "some_value3", "my_array" : [ { "num_field" : 250, "s_field" : "aaa" }, { "num_field" : 100, "s_field" : "bbb" } ] })
WriteResult({ "nInserted" : 1 })
>

Now, let's run the query with the projection:

> db.projection_test.find({ "my_array.0.num_field": { $lt: 300 } }, {"some_field": 1, "my_array.0.num_field": 1})
{ "_id" : ObjectId("53f9e04d7c6631fa3b232bb0"), "some_field" : "some_value1", "my_array" : [ {  }, {  } ] }
{ "_id" : ObjectId("53f9e0617c6631fa3b232bb2"), "some_field" : "some_value3", "my_array" : [ {  }, {  } ] }
> 

So, the query match on the field of the concretely named array element works, but the projection clearly doesn't. It returns empty objects for the elements "my_array.0".

Participants:

 Description   

When you query for documents that contain an array whose elements themselves are (embedded) objects, and then you try to project a field of a concretely named array element (dot notation) into the result set, the query engine doesn't return that field but rather returns that array element as empty object instead.



 Comments   
Comment by Ramon Fernandez Marina [ 28/Aug/14 ]

tomzahn, I've opened SERVER-15083 to see if there's room for improvement in this area.

Comment by Ramon Fernandez Marina [ 28/Aug/14 ]

tomzahn, it is ambiguous whether "0" refers to a nested field name or to a position in the array. For instance, what should the following projection return?

t.insert({a: [{"0": "foo", "bar": "baz"}, {"a": "b"}]});
t.find({}, {"a.0": 1});

One answer is that "0" should be interpreted as an array position, meaning that we should project just the first array element. The transformed document would then be:

{a: [ {"0": "foo", "bar": "baz"} ]}

Another answer is that "0" should be interpreted just like any other field name, and should be used to project within each nested document. Under this interpretation, the result is:

{ "a" : [ { "0" : "foo" }, {  } ] }

Our projection language chooses the latter interpretation. One possible workaround may be to use the $slice operator, which is designed for projecting array elements based on position.

Regards,
Ramón.

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