...
Given the following document: db.collection.insertOne({ items: [ { _id: ObjectId, name: 'foobar' {{ }}} ] }); Trying to `$unwind` the field path `$items.name` outputs nothing. On the other hand, the output of this: db.collection.aggregate([ { $project: { {{ type: { $type: '$items.name' }}} {{ }}} {{ }}} ]); is the following: {{{}} "_id" : ObjectId("..."), "type" : "array" } If the expression `$items.name` resolves to an array then why can I not `$unwind` this field path?
JIRAUSER1254095 commented on Wed, 17 Jan 2024 17:42:50 +0000: kateryna.kamenieva@mongodb.com christopher.harris@mongodb.com may we get an update on this ticket? It's been in "Investigating" status for quite sometime. Please refer to SERVER-73888 if you need additional help reproducing it. william.tan commented on Wed, 12 Apr 2023 23:11:15 +0000: Changing the type of this ticket to "Bug" upon customer request. JIRAUSER1269373 commented on Fri, 10 Feb 2023 18:32:11 +0000: @Johnny Shields haha I know that I can use `$project`, in my actual implementation I was using `$addFields` intentionally. JIRAUSER1254095 commented on Fri, 10 Feb 2023 18:16:29 +0000: @christopher.harris@mongodb.com > When fixing this ticket, please also verify that the behavior of the $unwind "preserveNullAndEmptyArrays" parameter true/false works correctly with subdocument fields. JIRAUSER1254095 commented on Fri, 10 Feb 2023 18:13:08 +0000: FYI, you can use a $project instead of $addFields in order to avoid modifying your documents. { "$project": { "p" => "$addresses.city" } } { "$unwind": "$p" } { "$group": { _id: "$p", counts: { "$sum": 1 } } } But this still should be fixed. JIRAUSER1269373 commented on Wed, 7 Sep 2022 12:54:32 +0000: @christopher.harris@mongodb.com Any update? It's been almost a year JIRAUSER1269373 commented on Wed, 22 Sep 2021 14:35:57 +0000: Hi @christopher.harris, The system might very well be working as designed currently. I'm not sure if this is a bug or a feature request, but I'll do my best to explain my use case for support of such functionality. First, to answer your request: the output I would expect when issuing an $unwind on "$arrayField.stringValue" (which is the equivalent to "$items.name" in my example, yes) is the same output which I would expect when issuing an $unwind on "$arrayField" itself. An excerpt of my use case is such: let parameterFieldPath = '$items.name'; db.collection.aggregate([ { $unwind: parameterFieldPath }, { $group: { _id: parameterFieldPath, items: { $push: '$$ROOT' } } ]); As seen above, I have to $unwind an array whose field path is specified in parameterFieldPath (which is "$items.name" in our example), and then $group the output documents by the same parameterFieldPath. parameterFieldPath is variable, and its value can be changed according to a user's settings. Currently, this doesn't work, and the only workaround is doing something like this: let parameterFieldPath = '$items.name'; db.collection.aggregate([ { // TODO: Remove stage once using version in which https://jira.mongodb.org/browse/SERVER-59713 is fixed $addFields: { parameterValue: parameterFieldPath } }, { $unwind: '$parameterValue' }, { $group: { _id: '$parameterValue', items: { $push: '$$ROOT' } } ]); But this leaves me with an unwanted temporary parameterValue field on each document. BTW the TODO is taken from our code I hope my use case was clear enough. As I've said before, I'm not sure whether this is a bug or a feature request - feel free to change the issue type accordingly. Thanks, Amit christopher.harris commented on Mon, 20 Sep 2021 19:33:00 +0000: Hi amitbeck@gmail.com, Based on our reading of the ticket description, we believe that the system may be working as designed currently. However, can you please give an example of what output you would expect when issuing an $unwind on "$arrayField.stringValue" ( "$items.name" in your example)? Based on the workaround you noted, it seems you are looking to create documents that each contain the value of the name field that is embedded in one of the subdocuments in the items array? The $unwind operator intends to have a field name that resolves to an array as its argument. This is why, as you've observed, the stage { $unwind: "$temp" } outputs results. In that situation, $temp now represents an array of string values that was generated from the original array of subdocuments. You could similarly choose to $unwind the array of subdocuments ( $items ) first and then rename or remove fields afterwards based on the desired logic. Furthermore, it is also possible to use or reference the individual values via the "$items.name" syntax in later aggregation stages after the "items" array has been unwound. How are you intending to use this field later in the aggregation pipeline? Similar confusion has come up before. The fact that the projection using the $type operator reported the field path as an array has to do with the fact that the $type aggregation operator does not examine array elements. Depending on the feedback you provide to the questions above, we may wish to convert this ticket into an improvement request. Best, Chris thomas.schubert commented on Mon, 13 Sep 2021 20:11:11 +0000: Thanks for the report, passing this along to the query team to investigate. Please continue to watch this ticket for updates. JIRAUSER1269373 commented on Wed, 1 Sep 2021 15:43:36 +0000: The workaround for now is something of the sorts: db.collection.aggregate([ { $addFields: temp: '$items.name' }, { $unwind: '$temp' } ]);
db.collection.insertOne({ items: [ { _id: ObjectId, name: 'foobar' {{ }}} ] }); db.collection.aggregate([ { $unwind: }}{{'$items.name' {{ }}} ]);{{}} Outputs nothing
Click on a version to see all relevant bugs
MongoDB Integration
Learn more about where this data comes from
Bug Scrub Advisor
Streamline upgrades with automated vendor bug scrubs
BugZero Enterprise
Wish you caught this bug sooner? Get proactive today.