[SERVER-17709] New aggregation operator - $unravel Created: 24/Mar/15  Updated: 03/Feb/16  Resolved: 06/Nov/15

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

Type: New Feature Priority: Minor - P4
Reporter: Scott Cote Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: stage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-11392 $unwind on subdocuments Closed
Participants:

 Description   

a stage operator that will unwind a subdocument so that a copy of the parent document is output along with each element of the subdocument - project every element of the subdocument to its own copy of the parent document. downstream pipeline stage operations may operate on the output akin to unwind.

NOTES on Priority: I currently work around this haphazardly if I can deterministically know in advance all of the elements that are in the subdocument.

NOTES on Affected Version: Not sure what to put here for this.



 Comments   
Comment by Scott Cote [ 11/Nov/15 ]

Ramon,

I think you are right. The functions are the same. As you know, I’m partial to $unravel because it is close in semantics to unwind, but infers a different behavior. Didn’t propose to overload unwind as that could introduce to much confusion. Keep up the good work and looking forward to sharing the 3.2 release news (vis a vis Craig Wilson) via the Dallas MongoDB Users Group.

Just glad to see it get in and get taken seriously.

Regards,

SCott

Comment by Ramon Fernandez Marina [ 06/Nov/15 ]

If I understand correctly the functionality requested in this ticket is the same as for SERVER-11392, but the semantics are still being discussed in both cases. Therefore I'm going to close this ticket as a duplicate of SERVER-11392.

Regards,
Ramón.

Comment by John A. De Goes [ 06/Nov/15 ]

Since this comes up more and more often on StackOverflow and mongdb-user, I suggest the following spec: $unravel takes a field name, which represents a subdocument, and pulls it apart into key/value pairs, replicating the whole document once for each key/value pair, and substituting the value part of the key/value pair into the field name.

{"foo": {"1": true, "2": false}}
 
-->
 
{$unravel: "$foo"}
 
-->
 
{"foo": true}
{"foo": false}

As with $unwind, there should also be an option to emit the key name. Otherwise this function won't be all that useful.

Comment by Asya Kamsky [ 07/Jul/15 ]

Same as SERVER-11392?

Comment by Ramon Fernandez Marina [ 24/Mar/15 ]

Hi scottccote,

external developers can't have JIRA tickets assigned to them. If you're interested in contributing you'll want to read the contributors page, and for code contributions the Getting Started section.

Another useful resource, which you've already found, is the mongodb-dev user group, where one can ask questions to other MongoDB developers.

Note that at the time of this writing we don't have a specific timeline for adding new aggregation operators, so if there's consensus that this new operator is a useful addition it may take some time to get merged.

Regards,
Ramón.

Comment by Scott Cote [ 24/Mar/15 ]

The third option allows a matcher to filter unraveled elements by value rather than using an existence check ....

Comment by Scott Cote [ 24/Mar/15 ]

3rd option for enhancement would have the unravel operator rename the original subdocument key "subkey1" to a generic key (mygenerickey) and add the key (unravelme) for the subdocument associated with "subkey1" .

{ "_id":"mykey_1" ,"a":"1" ,"unravelme":"x" ,"child":100 ,"b":"2" } { "_id":"mykey_1" ,"a":"1" ,"unravelme","y" ,"child":200 ,"b":"2" } { "_id":"mykey_1" ,"a":"1" ,"unravelme","z" ,"child":300 ,"b":"2" } { "_id":"mykey_2" ,"a":"2" ,"unravelme":"I" ,"child":10 ,"c":"22" ,"x":41 } { "_id":"mykey_2" ,"a":"2" ,"unravelme":"w" ,"child":101 ,"c":"22" ,"x":41 } { "_id":"mykey_2" ,"a":"2" ,"unravelme":"x" ,"child":101" "x":41 ,"c":"22" } { "_id":"mykey_2" ,"a":"2" ,"unravelme":"z" ,"child":301 ,"c":"22" ,"x":41 }

Doing this sidesteps the whole overwriting the parent key value (and if there is a collision - fail the stage.

Comment by Scott Cote [ 24/Mar/15 ]

here is a typical input collection

{
  "_id":"mykey_1"
 ,"a":"1"
 ,"unravelme":{"x":100,"y":200,"z":300}
 ,"b":"2" 
}
{
  "_id":"mykey_2"
 ,"a":"2"
 ,"unravelme":{"l":10,"w":101,"x":101,"z":301}
 ,"c":"22"
 ,"x":41
}

db.inventory.aggregate( [ { $unravel : "$unravelme"} ] )
{
  "_id":"mykey_1"
 ,"a":"1"
 ,"x":100
 ,"b":"2" 
}
 
{
  "_id":"mykey_1"
 ,"a":"1"
 ,"y":200
 ,"b":"2" 
}
 
{
  "_id":"mykey_1"
 ,"a":"1"
 ,"z":300
 ,"b":"2" 
}
{
  "_id":"mykey_2"
 ,"a":"2"
 ,"l":10
 ,"c":"22"
 ,"x":41
}
 
{
  "_id":"mykey_2"
 ,"a":"2"
 ,"w":101
 ,"c":"22"
 ,"x":41
}
 
{
  "_id":"mykey_2"
 ,"a":"2"
 "x":101
 ,"c":"22"
}
 
{
  "_id":"mykey_2"
 ,"a":"2"
 ,"z":301
 ,"c":"22"
 ,"x":41
}

This operation would by default overwrite a parent element that has the same name. Notice that the doc with id "mykey_2" has one of its outputs with the x attribute changed from 41 to 101 per the subdocument.

Enhancement would be include options that:

1. preserve the parent key/value pair and fail the operation
2. allow string operations of the projected key (unravelme.w -> ur_w, unravelme.x -> ur_x,....)

Comment by Scott Cote [ 24/Mar/15 ]

i have started working on this, but I cannot assign the jira to myself - can someone assign it to me?

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