From d38a777b58b8e5cf2dab1fd515df8531950e5299 Mon Sep 17 00:00:00 2001 From: Maya Raman Date: Thu, 19 Dec 2024 12:22:58 -0800 Subject: [PATCH] DOCSP-40066: Support SelectMany inside Project/Select (#373) (cherry picked from commit 8c2bdc5509bb92c20bb7cde89228a064b2b9046d) --- source/fundamentals/linq.txt | 90 +++++++++++++++++++ .../fundamentals/code-examples/linq.cs | 5 ++ 2 files changed, 95 insertions(+) diff --git a/source/fundamentals/linq.txt b/source/fundamentals/linq.txt index e66f0fcf..03ff3426 100644 --- a/source/fundamentals/linq.txt +++ b/source/fundamentals/linq.txt @@ -320,6 +320,96 @@ following documents: { "date" : ISODate("2012-12-05T00:00:00Z"), "grade" : "A", "score" : 13 } { "date" : ISODate("2012-05-17T00:00:00Z"), "grade" : "A", "score" : 11 } +Nested Statements ++++++++++++++++++ + +You can chain or nest ``Select`` and ``SelectMany`` statements to unwind nested +arrays. Consider a collection that contains documents with a **new** schema. These +documents contain a ``restaurants`` field, which holds an array of documents +represented by the ``Restaurant`` class. The documents within the array each have +a ``grades`` field that holds an array of documents represented by +the ``Grade`` class. The following code is an example of a single document in +this collection: + +.. code-block:: json + + { + "_id": { "$oid": ... }, + "restaurants": [ + { + "_id": { ... } , + "address": { ... }, + "name": "Tov Kosher Kitchen", + "grades": [ + { + "date" : ISODate("2014-11-24T00:00:00Z"), + "grade" : "Z", + "score" : 20.0 + }, + { + "date" : ISODate("2013-01-17T00:00:00Z"), + "grade" : "A", + "score" : 13.0 + } + ] + ... + }, + { + "_id": { ... } , + "address": { ... }, + "name": "Harriet's Kitchen", + "grades": [ + { + "date" : ISODate("2014-04-19T00:00:00Z"), + "grade" : "B", + "score" : 12.0 + } + ], + ... + }, + ... + ] + } + +You can nest ``SelectMany`` statements within ``SelectMany`` or ``Select`` +statements. The following example nests a ``SelectMany`` statement within a +``Select`` statement to retrieve an array from each document in the collection. +Each array holds all grade objects from all restaurants in each document. + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/linq.cs + :language: csharp + :start-after: start-nested-SelectMany + :end-before: end-nested-SelectMany + + .. output:: + :visible: false + :language: json + + // output for first document in collection + [ + { "date" : ISODate("2014-11-24T00:00:00Z"), + "grade" : "Z", + "score" : 20.0 + }, + { "date" : ISODate("2013-01-17T00:00:00Z"), + "grade" : "A", + "score" : 13.0 + }, + { + "date" : ISODate("2014-04-19T00:00:00Z"), + "grade" : "B", + "score" : 12.0 + }, + ... + ], + // output for second document in collection + [ + ... + ] + $group ~~~~~~ diff --git a/source/includes/fundamentals/code-examples/linq.cs b/source/includes/fundamentals/code-examples/linq.cs index de5ab12e..9154c2ab 100644 --- a/source/includes/fundamentals/code-examples/linq.cs +++ b/source/includes/fundamentals/code-examples/linq.cs @@ -81,6 +81,11 @@ public class Ingredient // end-ingredient-model +// start-nested-SelectMany +var query = queryableCollection + .Select(r => r.Restaurants.SelectMany(r => r.Grades)); +// end-nested-SelectMany + // start-bitAnd-example var query = queryableCollection