[SERVER-1608] Retrieving only selected document(s) from within an embedded array Created: 10/Aug/10  Updated: 06/Apr/11  Resolved: 17/Feb/11

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

Type: Question Priority: Major - P3
Reporter: m savy Assignee: Eliot Horowitz (Inactive)
Resolution: Duplicate Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-828 Support for selecting array elements ... Closed
Participants:

 Description   

I am not completely certain, but I believe at present it is not possible to return only selected document(s) from within an embedded array. For instance;

document A {
user_name: example_user,
remaining_tokens: 40,
assignees_array[

{UUID: 7, next_checkin_time: <some_unix_time>, expires: <some_unix_time>}

,

{UUID: 1F0, next_checkin_time: <some_unix_time>, expires: <some_unix_time>}

, ... ]
}

If my program has knowledge of the UUID, and wishes to see only the sub-document (e.g. If we queried for UUID 7 and then read the next_checkin_time and some other fields).

db.my_collection.find("assignees_array.UUID":"1F0"} =>

{UUID: 1F0, next_checkin_time: <some_unix_time>, expires: <some_unix_time>}

At present I do not know of a way that it is possible to achieve this, as it returns the entire parent document and all array elements (losing some of the benefit of selecting on the basis of the embedded document's UUID), so you have to iterate to find the correct item.



 Comments   
Comment by Eliot Horowitz (Inactive) [ 17/Feb/11 ]

See SERVER-2238

Comment by Scott Roberts [ 12/Nov/10 ]

I wanted to add to this another request as I'm not sure it was entirely detailed in the above. We have the same request for embedded documents to only return the array element that was found during the query. In addition, I think it would be useful that if the element is found the array of another document, that those two are combined together into a return array instead of being pared down arrays in separate documents. An example is probably best to illustrate what I'm hoping for.

I have two documents stored looking like this:

{name:foo locs:[

{ x:3 y:4 }

,

{ x:3 y:5 }

,

{ x:4 y:5 }

]},
{name:bar locs:[

{ x:3 y:4 }

]}

I would like to perform this query (or something similar) to get the locations matching the value x:3 where I don't care about any of the parent info:

db.things.find(

{locs.x:3}

,

{locs:1}

)

Right now I'd get something like this:

{_id:"abc..123" locs:[

{ x:3 y:4 }

,

{ x:3 y:5 }

,

{ x:4 y:5 }

]},
{_id:"abc...456" locs:[

{ x:3 y:4 }

]}

This has two problems, first the

{x:4, y:5}

element shows up even though there is not a match in the array, just because there is a document match. Second the two documents still need to be combined. It would be great to get a response like this:

{locs:[

{ x:3 y:4 }

,

{ x:3 y:5 }

,

{ x:3 y:4 }

]}

Comment by m savy [ 10/Aug/10 ]

Actually, one can exclude the parent document's other fields by using exclusion

e.g.
db.my_collection.find("assignees_array.UUID":"1F0"},

{"assignees_array" : 1}

);

but the other array elements will still be there, that you aren't interested in.

edit: if this was a separate collection versus embedded [for assignees array], you would lose the atomic update ability, and therefore if a crash occurred between assigning the user and changing the "assigned" counter, there would be db inconsistencies.

One could count the assigned tokens manually each time, but this is going to be very inefficient in the situation where you need to check the count on every access.

edit2: this may be similar http://jira.mongodb.org/browse/SERVER-142 ?

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