@@ -219,3 +219,139 @@ following API documentation:
219219- `Where() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Where.html>`__
220220- `GroupBy() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.GroupBy.html>`__
221221- `Select() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.MongoQueryable.Select.html>`__
222+
223+ .. TODO: integrate into existing page
224+
225+ Sample Class
226+ ------------
227+
228+ The code examples in this guide demonstrate how you can use builders to
229+ create types to interact with documents in the sample collection ``plants.flowers``.
230+ Documents in this collection are modeled by the following ``Flower`` class:
231+
232+ .. literalinclude:: /includes/fundamentals/code-examples/builders.cs
233+ :language: csharp
234+ :dedent:
235+ :start-after: start-model
236+ :end-before: end-model
237+
238+ Each builder class takes a generic type parameter
239+ ``TDocument`` which represents the type of document that you are working
240+ with. In this guide, the ``Flower`` class is the document type used in
241+ each builder class example.
242+
243+ .. _csharp-builders-aggregation:
244+
245+ Build an Aggregation Pipeline
246+ -----------------------------
247+
248+ The ``PipelineDefinitionBuilder`` class provides a type-safe interface for
249+ defining an **aggregation pipeline**. An aggregation pipeline is a series of
250+ stages that are used to transform a document. Suppose you want to create a
251+ pipeline that performs the following operations:
252+
253+ - Matches all documents with "spring" in the ``Season`` field
254+ - Sorts the results by the ``Category`` field
255+ - Groups the documents by category and shows the average price and total
256+ available for all documents in that category
257+
258+ Use ``PipelineDefinitionBuilder`` classes to build the pipeline:
259+
260+ .. code-block:: csharp
261+
262+ var sortBuilder = Builders<Flower>.Sort.Ascending(f => f.Category);
263+ var matchFilter = Builders<Flower>.Filter.AnyEq(f => f.Season, "spring");
264+
265+ var pipeline = new EmptyPipelineDefinition<Flower>()
266+ .Match(matchFilter)
267+ .Sort(sortBuilder)
268+ .Group(f => f.Category,
269+ g => new
270+ {
271+ name = g.Key,
272+ avgPrice = g.Average(f => f.Price),
273+ totalAvailable = g.Sum(f => f.Stock)
274+ }
275+ );
276+
277+ The preceding example creates the following pipeline:
278+
279+ .. code-block:: json
280+
281+ [{ "$match" : { "season" : "spring" } }, { "$sort" : { "category" : 1 } }, { "$group" : { "_id" : "$category", "avgPrice" : { "$avg" : "$price" }, "totalAvailable" : { "$sum" : "$stock" } } }]
282+
283+ You can add stages to your pipeline that don't have corresponding type-safe
284+ methods in the ``PipelineDefinitionBuilder`` interface by providing your query
285+ as a ``BsonDocument`` to the `AppendStage() method
286+ <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.AppendStage.html>`__.
287+
288+ .. code-block:: csharp
289+
290+ var pipeline = new EmptyPipelineDefinition<BsonDocument>().AppendStage<BsonDocument, BsonDocument, BsonDocument>("{ $set: { field1: '$field2' } }");
291+
292+ .. note::
293+
294+ When using a ``BsonDocument`` to define your pipeline stage, the driver does
295+ not take into account any ``BsonClassMap``, serialization attributes or
296+ serialization conventions. The field names used in the ``BsonDocument`` must
297+ match those stored on the server.
298+
299+ For more information on providing a query as a ``BsonDocument``, see our
300+ :ref:`FAQ page <csharp-faq-unsupported-expressions>`.
301+
302+ To learn more about the Aggregation Pipeline, see the
303+ :manual:`Aggregation Pipeline </core/aggregation-pipeline/>` server manual page.
304+
305+ .. _csharp-builders-out:
306+
307+ Write Pipeline Results to a Collection
308+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309+
310+ You can write the documents returned from an aggregation pipeline to a
311+ collection by creating an ``$out`` stage at the end of your aggregation
312+ pipeline. To create an ``$out`` stage, call the ``Out()`` method on a
313+ ``PipelineStageDefinitionBuilder``. The ``Out()`` method requires the name of
314+ the collection you want to write the documents to.
315+
316+ The following example builds an aggregation pipeline that matches all documents
317+ with a ``season`` field value of ``"Spring"`` and outputs them to
318+ a ``springFlowers`` collection:
319+
320+ .. code-block:: csharp
321+
322+ var outputCollection = database.GetCollection("springFlowers");
323+ var matchFilter = Builders<Flower>.Filter.AnyEq(f => f.Season, "spring");
324+
325+ // Creates an aggregation pipeline and outputs resulting documents to a new collection.
326+ var pipeline = new EmptyPipelineDefinition<Flower>()
327+ .Match(matchFilter)
328+ .Out(outputCollection);
329+
330+ You can write the results of an aggregation pipeline to a time series collection
331+ by specifying a ``TimeSeriesOption`` object and passing it as the second
332+ parameter to the ``Out()`` method.
333+
334+ Imagine that the documents in the ``plants.flowers`` collection contain a ``datePlanted`` field that
335+ holds BSON date values. You can store the documents in this collection in a time
336+ series collection by using the ``datePlanted`` field as the time field.
337+
338+ The following example creates a ``TimeSeriesOptions`` object and specifies
339+ ``datePlanted`` as the ``timeField``. It then builds an aggregation pipeline that matches all documents
340+ with a ``season`` field value of ``"Spring"`` and outputs them to a
341+ time series collection called ``springFlowerTimes``.
342+
343+ .. code-block:: csharp
344+
345+ var timeSeriesOptions = new TimeSeriesOptions("datePlanted");
346+ var collectionName = "springFlowerTimes"
347+ var matchFilter = Builders<Flower>.Filter.AnyEq(f => f.Season, "spring");
348+
349+ // Creates an aggregation pipeline and outputs resulting documents to a time series collection.
350+ var pipeline = new EmptyPipelineDefinition<Flower>()
351+ .Match(matchFilter)
352+ .Out(collectionName, timeSeriesOptions);
353+
354+ To learn more about time series collections, see :ref:`csharp-time-series`.
355+
356+
357+ - `PipelineDefinitionBuilder <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.PipelineDefinitionBuilder.html>`__
0 commit comments