[SERVER-4588] aggregation: add option to $unwind to emit array index Created: 30/Dec/11  Updated: 16/Nov/21  Resolved: 11/Sep/15

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

Type: New Feature Priority: Major - P3
Reporter: Daniel Pasette (Inactive) Assignee: Charlie Swanson
Resolution: Done Votes: 19
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on DRIVERS-234 Aggregation Builder Support for 3.2 Closed
is depended on by CSHARP-1433 Add option to $unwind to emit array i... Closed
is depended on by JAVA-1995 Add option to $unwind to emit array i... Closed
Duplicate
is duplicated by SERVER-14565 New aggregation operators Closed
Related
is related to SERVER-20595 Unwind with includeArrayIndex produce... Closed
Backwards Compatibility: Fully Compatible
Sprint: Quint 9 09/18/15
Participants:

 Description   

There may be times when the index of an array element is interesting. $unwind
could provide an option to emit this. For example

instead of just

db.runCommand({ aggregate:"c", pipeline:[
    { $unwind: "$arrayField"}
]});

consider also supporting something like this:

db.runCommand({ aggregate:"c", pipeline:[
    { $unwind: { path: "$arrayField", includeArrayIndex: boolean }}
]});

The effect of this is the same except that it also adds a new field index
to the output which is assigned the index of the array element.



 Comments   
Comment by Githook User [ 13/Oct/15 ]

Author:

{u'username': u'cswanson310', u'name': u'Charlie Swanson', u'email': u'charlie.swanson@mongodb.com'}

Message: SERVER-4588 Add option to $unwind stage to include array index in output

Adds logic to $lookUp to handle the includeArrayIndex parameter from
the $unwind stage if the $lookUp stage had coalesced with an $unwind stage.
Branch: artree
https://github.com/10gen/mongo-enterprise-modules/commit/56a9d68a2e0ab5eda765df97a41c0d17f69aaf0f

Comment by Githook User [ 11/Sep/15 ]

Author:

{u'username': u'cswanson310', u'name': u'Charlie Swanson', u'email': u'charlie.swanson@mongodb.com'}

Message: SERVER-4588 Add option to $unwind stage to include array index in output

Adds a includeArrayIndex option to the $unwind stage. If this option is
specified, the $unwind stage will output values with the structure

{index: <array index>, value: <array value>}

instead of just the array value.

Note this does not affect the behavior non-arrays or empty arrays. If
includeArrayIndex and preserveNullAndEmptyArrays are both specified, values
from a non-empty array will have an index attached, and all other values will
pass through unchanged.
Branch: master
https://github.com/mongodb/mongo/commit/522f5a2bff9cc41e56520af2deedd62654f23552

Comment by Githook User [ 11/Sep/15 ]

Author:

{u'username': u'cswanson310', u'name': u'Charlie Swanson', u'email': u'charlie.swanson@mongodb.com'}

Message: SERVER-4588 Add option to $unwind stage to include array index in output

Adds logic to $lookUp to handle the includeArrayIndex parameter from
the $unwind stage if the $lookUp stage had coalesced with an $unwind stage.
Branch: master
https://github.com/10gen/mongo-enterprise-modules/commit/56a9d68a2e0ab5eda765df97a41c0d17f69aaf0f

Comment by John A. De Goes [ 07/Jul/15 ]

I'd amend my suggestion to just have a `$zip` that can zip two arrays together:

{a: [1, 2, 3], b: ["a","b"]}

> {ab: {$zip: ["$a", "$b"]}}

>

{ab: [[1, "a"], [2, "b"]]}

Then if necessary a separate `$range` operator could generate an array with integral values falling between the specified upper and lower bound.

These operators are more primitive and can be composed together in many more useful ways than a special case flag for $unwind.

Comment by John A. De Goes [ 24/Sep/14 ]

More composable would be an option to bundle each index into the array elements, i.e. `zipWithIndex`:

{"$zipWithIndex": "fruit_ranking"}

->

{"fruit_ranking": [[0, "Apple"], [1, "Orange"], [2, "Grape"], [3, "Kiwi"], [4, "Mango"], [5, "Pear"]]}

With this functionality, it becomes easy to unwind both results and extract out the index or the value or both.

Comment by Oliver Yeh [ 11/Jan/14 ]

This would be extremely useful for me too.

I have this use case.

Tastiest Fruit Rankings:

{"date": "Jan 1st",
 "fruit_ranking": ["Apple", "Orange", "Grape", "Kiwi", "Mango", "Pear"]},
{"date": "Jan 2nd",
 "fruit_ranking": ["Orange", "Grape", "Kiwi", "Pear", "Apple"]},
.....
{"date": "Dec 31st",
 "fruit_ranking":  ["Kiwi", "Apple", "Grape", "Mange", "Pear"]}

I'm trying to grab the ranking of "Pear" for each day Jan 1st - Dec 31st and right now I need to grab all of the arrays back and do indexOf
in my application. Would speed up my application quite a bit if theres some way of doing this in MongoDB and just return the index of "Pear" instead of the whole Array.

Comment by Ryan Brothers [ 26/Dec/12 ]

I agree - this would be extremely useful for me too as the array indexes returned could be used to update the matched subdocuments by using dot notation. For example, if subdocuments 0, 1, and 3 were returned from a call to aggregate with $unwind and then $match to filter the subdocuments, the matched subdocuments could be updated with:

db.test.update(
    {_id: 1},
    {
        $set: {
            "arrayField.0.testField": "test0",
            "arrayField.1.testField": "test1",
            "arrayField.3.testField": "test3"
        }
    }
);

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