From 4a715b6bf353a8542f5f166033fd50473bf20fd2 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 13 Nov 2024 14:36:23 -0500 Subject: [PATCH 1/7] DOCSP-45003: Specify Fields to Include --- source/fundamentals/crud/read-operations.txt | 2 + .../crud/read-operations/project.txt | 154 ++++++++++++++++++ .../fundamentals/code-examples/Project.cs | 91 +++++++++++ 3 files changed, 247 insertions(+) create mode 100644 source/fundamentals/crud/read-operations/project.txt create mode 100644 source/includes/fundamentals/code-examples/Project.cs diff --git a/source/fundamentals/crud/read-operations.txt b/source/fundamentals/crud/read-operations.txt index 60cf8425..02936834 100644 --- a/source/fundamentals/crud/read-operations.txt +++ b/source/fundamentals/crud/read-operations.txt @@ -11,9 +11,11 @@ Read Operations :caption: Read Operations Retrieve Data + /fundamentals/crud/read-operations/project Count Documents Monitor Data Changes - :ref:`csharp-retrieve` +- :ref: `csharp-project` - :ref:`csharp-count-documents` - :ref:`csharp-change-streams` diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt new file mode 100644 index 00000000..17a4bf74 --- /dev/null +++ b/source/fundamentals/crud/read-operations/project.txt @@ -0,0 +1,154 @@ +.. _csharp-project: + +======================== +Specify Fields To Return +======================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: read, filter, project, select + +Overview +-------- + +In this guide, you can learn how to specify which fields to return from a read +operation by using a **projection**. A projection is a document that specifies +which fields MongoDB returns from a query. + +Sample Data +~~~~~~~~~~~ + +The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` +database from the :atlas:`Atlas sample datasets `. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see the +:atlas:`Get Started with Atlas ` guide. + +The examples on this page use the following ``Restaurant`` and ``Address`` classes to model +the documents in the collection: + +.. literalinclude:: /includes/fundamentals/code-examples/Project.cs + :start-after: start-model + :end-before: end-model + :language: csharp + +Projection Types +---------------- + +You can use a projection to specify which fields to include in a return +document, or to specify which fields to exclude. + +When specifying certain fields to include in a projection, all other fields are implicitly +excluded (except the ``_id`` field, which is included by default). You cannot combine +inclusion and exclusion statements in a single projection, unless you are excluding the +``_id`` field. + +To remove the ``_id`` field from the returned document, you must +:ref:`explicitly exclude it `. + +Specify Fields to Include +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To specify the fields to include from the result, chain the ``Projection()`` method +to the ``Find()`` method. When calling the ``Projection()`` method, you must pass in the +projection definition as a parameter. You can construct a projection definition by using +the ``Builders.Projection.Include()`` method and passing in the field name to include +as a parameter. This method can be chained to include multiple fields in the projection. + +The following example uses the ``Find()`` method to find all restaurants in which the ``name`` +field value is ``"Emerald Pub"``. Then, the code calls the ``projection()`` and ``exclude()`` +methods to instruct the find operation to omit the ``name`` and ``address`` fields +in the result: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/Project.cs + :start-after: start-project-include + :end-before: end-project-include + :language: csharp + :dedent: + + .. output:: + :visible: false + + { "_id" : ObjectId("..."), "cuisine" : "American", "name" : "Emerald Pub" } + { "_id" : ObjectId("..."), "cuisine" : "American", "name" : "Emerald Pub" } + +.. _csharp-project-exclude-id: + +Exclude the ``_id`` Field +~~~~~~~~~~~~~~~~~~~~~~~~~ + +When specifying fields to include, you can also exclude the ``_id`` field from +the returned document. + +The following example runs the same query as the preceding example, but +excludes the ``_id`` field from the projection: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/Project.cs + :start-after: start-project-include-without-id + :end-before: end-project-include-without-id + :language: csharp + :dedent: + + .. output:: + :visible: false + + { "cuisine" : "American", "name" : "Emerald Pub" } + { "cuisine" : "American", "name" : "Emerald Pub" } + +Specify Fields to Exclude +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To specify the fields to include from the result, chain the ``Projection()`` method +to the ``Find()`` method. You can exclude fields in your projection by using +the ``Builders.Projection.Exclude()`` method and passing in the field name to exclude +as a parameter. This method can be chained to exclude multiple fields in the projection. + +The following example uses the ``Find()`` method to find all restaurants in which the ``name`` +field value is ``"Emerald Pub"``. It then uses a projection to exclude the ``cuisine`` +field from the returned documents: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/fundamentals/code-examples/Project.cs + :start-after: start-project-exclude + :end-before: end-project-exclude + :language: csharp + :dedent: + + .. output:: + :visible: false + + { "_id" : ObjectId("..."), "address" : { "building" : "308", "coord" : [-74.008493599999994, 40.725807199999998], "street" : "Spring Street", "zipcode" : "10013" }, "borough" : "Manhattan", "grades" : [{ "date" : ISODate("2014-02-24T00:00:00Z"), "grade" : "A", "score" : 5 }, { "date" : ISODate("2013-08-26T00:00:00Z"), "grade" : "A", "score" : 13 }, { "date" : ISODate("2013-03-04T00:00:00Z"), "grade" : "A", "score" : 12 }, { "date" : ISODate("2012-06-25T00:00:00Z"), "grade" : "A", "score" : 10 }, { "date" : ISODate("2011-12-23T00:00:00Z"), "grade" : "A", "score" : 10 }, { "date" : ISODate("2011-07-26T00:00:00Z"), "grade" : "C", "score" : 32 }], "name" : "Emerald Pub", "restaurant_id" : "40367329" } + { "_id" : ObjectId("..."), "address" : { "building" : "18301", "coord" : [-73.791184999999999, 40.740119999999997], "street" : "Horace Harding Expressway", "zipcode" : "11365" }, "borough" : "Queens", "grades" : [{ "date" : ISODate("2014-05-07T00:00:00Z"), "grade" : "A", "score" : 12 }, { "date" : ISODate("2013-04-30T00:00:00Z"), "grade" : "A", "score" : 9 }, { "date" : ISODate("2012-03-01T00:00:00Z"), "grade" : "A", "score" : 13 }], "name" : "Emerald Pub", "restaurant_id" : "40668598" } + +Additional Information +---------------------- + +To learn more about projections, see the :manual:`Project Fields guide +` in the MongoDB Server Manual. + +API Documentation +~~~~~~~~~~~~~~~~~ + +To learn more about any of the functions or types discussed in this +guide, see the following API Documentation: + +- `Find() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.IMongoCollectionExtensions.Find.html>`_ +- `Projection <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Builders-1.Projection.html>`_ +- `Include() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Include.html>`_ +- `Exclude() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ProjectionDefinitionBuilder-1.Exclude.html>`_ \ No newline at end of file diff --git a/source/includes/fundamentals/code-examples/Project.cs b/source/includes/fundamentals/code-examples/Project.cs new file mode 100644 index 00000000..d6f1d111 --- /dev/null +++ b/source/includes/fundamentals/code-examples/Project.cs @@ -0,0 +1,91 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Driver; + +public class LimitSortSkip +{ + // Replace with your connection string + private const string MongoConnectionString = ""; + + public static void Main(string[] args) + { + var mongoClient = new MongoClient(MongoConnectionString); + var database = mongoClient.GetDatabase("sample_restaurants"); + var collection = database.GetCollection("restaurants"); + + { + // start-project-include + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection + .Include("name") + .Include("cuisine"); + + var results = collection.Find(filter).Project(projection).ToList(); + foreach (var result in results) + { + Console.WriteLine(result.ToJson()); + } + // end-project-include + } + + { + // start-project-include-without-id + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection + .Include("name") + .Include("cuisine") + .Exclude("_id"); + + var results = collection.Find(filter).Project(projection).ToList(); + foreach (var result in results) + { + Console.WriteLine(result.ToJson()); + } + // end-project-include-without-id + } + + { + // start-project-exclude + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection + .Exclude("cuisine"); + + var results = collection.Find(filter).Project(projection).ToList(); + foreach (var result in results) + { + Console.WriteLine(result.ToJson()); + } + // end-project-exclude + } + + } +} + +// start-model +public class Restaurant { + public ObjectId? Id { get; set; } + + [BsonElement("name")] + public string? Name { get; set; } + + [BsonElement("cuisine")] + public string? Cuisine { get; set; } + + [BsonElement("address")] + public Address? Address { get; set; } +} + +public class Address +{ + public string Building { get; set; } + + [BsonElement("coord")] + public double[] Coordinates { get; set; } + + public string Street { get; set; } + + [BsonElement("zipcode")] + public string ZipCode { get; set; } +} +// end-model \ No newline at end of file From 4a6019b2b5145343ea1c77b09c9ffe7cfb1b6ed6 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 13 Nov 2024 14:45:37 -0500 Subject: [PATCH 2/7] Fix --- .../crud/read-operations/project.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt index 17a4bf74..10320c37 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/fundamentals/crud/read-operations/project.txt @@ -27,10 +27,9 @@ which fields MongoDB returns from a query. Sample Data ~~~~~~~~~~~ -The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants`` -database from the :atlas:`Atlas sample datasets `. To learn how to create a -free MongoDB Atlas cluster and load the sample datasets, see the -:atlas:`Get Started with Atlas ` guide. +The examples in this guide use the ``sample_restaurants.restaurants`` collection +from the :atlas:`Atlas sample datasets `. To learn how to create a +free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. The examples on this page use the following ``Restaurant`` and ``Address`` classes to model the documents in the collection: @@ -57,15 +56,15 @@ To remove the ``_id`` field from the returned document, you must Specify Fields to Include ~~~~~~~~~~~~~~~~~~~~~~~~~ -To specify the fields to include from the result, chain the ``Projection()`` method -to the ``Find()`` method. When calling the ``Projection()`` method, you must pass in the +To specify the fields to include from the result, chain the ``Project()`` method +to the ``Find()`` method. When calling the ``Project()`` method, you must pass in the projection definition as a parameter. You can construct a projection definition by using the ``Builders.Projection.Include()`` method and passing in the field name to include as a parameter. This method can be chained to include multiple fields in the projection. The following example uses the ``Find()`` method to find all restaurants in which the ``name`` -field value is ``"Emerald Pub"``. Then, the code calls the ``projection()`` and ``exclude()`` -methods to instruct the find operation to omit the ``name`` and ``address`` fields +field value is ``"Emerald Pub"``. Then, the code calls the ``Project()`` +method to instruct the find operation to include the ``name`` and ``address`` fields in the result: .. io-code-block:: @@ -112,7 +111,7 @@ excludes the ``_id`` field from the projection: Specify Fields to Exclude ~~~~~~~~~~~~~~~~~~~~~~~~~ -To specify the fields to include from the result, chain the ``Projection()`` method +To specify the fields to include from the result, chain the ``Project()`` method to the ``Find()`` method. You can exclude fields in your projection by using the ``Builders.Projection.Exclude()`` method and passing in the field name to exclude as a parameter. This method can be chained to exclude multiple fields in the projection. From db7c687ccd36a3036720c48d456319072151fbb3 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 13 Nov 2024 14:47:46 -0500 Subject: [PATCH 3/7] Fix --- source/fundamentals/crud/read-operations.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/crud/read-operations.txt b/source/fundamentals/crud/read-operations.txt index 02936834..329b1e40 100644 --- a/source/fundamentals/crud/read-operations.txt +++ b/source/fundamentals/crud/read-operations.txt @@ -16,6 +16,6 @@ Read Operations Monitor Data Changes - :ref:`csharp-retrieve` -- :ref: `csharp-project` +- :ref:`csharp-project` - :ref:`csharp-count-documents` - :ref:`csharp-change-streams` From a6f039d8fa2c172a2e51d12e3d1297ebb1da1ff9 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Wed, 13 Nov 2024 14:56:16 -0500 Subject: [PATCH 4/7] Fix --- source/fundamentals/crud/read-operations/project.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt index 10320c37..c5a6c793 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/fundamentals/crud/read-operations/project.txt @@ -139,7 +139,7 @@ Additional Information ---------------------- To learn more about projections, see the :manual:`Project Fields guide -` in the MongoDB Server Manual. +` in the {+mdb-server+} manual. API Documentation ~~~~~~~~~~~~~~~~~ From dbbabec18c139110469b96b351ff2c0fbbaba9b5 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Thu, 14 Nov 2024 09:15:47 -0500 Subject: [PATCH 5/7] SA feedback --- source/fundamentals/crud/read-operations/project.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt index c5a6c793..8ab50efb 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/fundamentals/crud/read-operations/project.txt @@ -64,7 +64,7 @@ as a parameter. This method can be chained to include multiple fields in the pro The following example uses the ``Find()`` method to find all restaurants in which the ``name`` field value is ``"Emerald Pub"``. Then, the code calls the ``Project()`` -method to instruct the find operation to include the ``name`` and ``address`` fields +method to instruct the find operation to include the ``name`` and ``cuisine`` fields in the result: .. io-code-block:: @@ -111,7 +111,7 @@ excludes the ``_id`` field from the projection: Specify Fields to Exclude ~~~~~~~~~~~~~~~~~~~~~~~~~ -To specify the fields to include from the result, chain the ``Project()`` method +To specify the fields to exclude from the result, chain the ``Project()`` method to the ``Find()`` method. You can exclude fields in your projection by using the ``Builders.Projection.Exclude()`` method and passing in the field name to exclude as a parameter. This method can be chained to exclude multiple fields in the projection. From fde82195f5f02505cd917203383fc5af1f725452 Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 15 Nov 2024 15:08:09 -0500 Subject: [PATCH 6/7] Address technical feedback --- .../crud/read-operations/project.txt | 8 ---- .../fundamentals/code-examples/Project.cs | 46 ++++--------------- 2 files changed, 9 insertions(+), 45 deletions(-) diff --git a/source/fundamentals/crud/read-operations/project.txt b/source/fundamentals/crud/read-operations/project.txt index 8ab50efb..fb64294e 100644 --- a/source/fundamentals/crud/read-operations/project.txt +++ b/source/fundamentals/crud/read-operations/project.txt @@ -31,14 +31,6 @@ The examples in this guide use the ``sample_restaurants.restaurants`` collection from the :atlas:`Atlas sample datasets `. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the :ref:``. -The examples on this page use the following ``Restaurant`` and ``Address`` classes to model -the documents in the collection: - -.. literalinclude:: /includes/fundamentals/code-examples/Project.cs - :start-after: start-model - :end-before: end-model - :language: csharp - Projection Types ---------------- diff --git a/source/includes/fundamentals/code-examples/Project.cs b/source/includes/fundamentals/code-examples/Project.cs index d6f1d111..2b83cc2f 100644 --- a/source/includes/fundamentals/code-examples/Project.cs +++ b/source/includes/fundamentals/code-examples/Project.cs @@ -3,7 +3,7 @@ using MongoDB.Bson.Serialization.Conventions; using MongoDB.Driver; -public class LimitSortSkip +public class Project { // Replace with your connection string private const string MongoConnectionString = ""; @@ -12,12 +12,12 @@ public static void Main(string[] args) { var mongoClient = new MongoClient(MongoConnectionString); var database = mongoClient.GetDatabase("sample_restaurants"); - var collection = database.GetCollection("restaurants"); + var collection = database.GetCollection("restaurants"); { // start-project-include - var filter = Builders.Filter.Eq("name", "Emerald Pub"); - var projection = Builders.Projection + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection .Include("name") .Include("cuisine"); @@ -31,8 +31,8 @@ public static void Main(string[] args) { // start-project-include-without-id - var filter = Builders.Filter.Eq("name", "Emerald Pub"); - var projection = Builders.Projection + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection .Include("name") .Include("cuisine") .Exclude("_id"); @@ -47,8 +47,8 @@ public static void Main(string[] args) { // start-project-exclude - var filter = Builders.Filter.Eq("name", "Emerald Pub"); - var projection = Builders.Projection + var filter = Builders.Filter.Eq("name", "Emerald Pub"); + var projection = Builders.Projection .Exclude("cuisine"); var results = collection.Find(filter).Project(projection).ToList(); @@ -60,32 +60,4 @@ public static void Main(string[] args) } } -} - -// start-model -public class Restaurant { - public ObjectId? Id { get; set; } - - [BsonElement("name")] - public string? Name { get; set; } - - [BsonElement("cuisine")] - public string? Cuisine { get; set; } - - [BsonElement("address")] - public Address? Address { get; set; } -} - -public class Address -{ - public string Building { get; set; } - - [BsonElement("coord")] - public double[] Coordinates { get; set; } - - public string Street { get; set; } - - [BsonElement("zipcode")] - public string ZipCode { get; set; } -} -// end-model \ No newline at end of file +} \ No newline at end of file From 04dcc4ebccc551aa9e422640f0db8eb6d2d1fcea Mon Sep 17 00:00:00 2001 From: Michael Morisi Date: Fri, 15 Nov 2024 15:08:50 -0500 Subject: [PATCH 7/7] Fix --- source/includes/fundamentals/code-examples/Project.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/includes/fundamentals/code-examples/Project.cs b/source/includes/fundamentals/code-examples/Project.cs index 2b83cc2f..e2013e6a 100644 --- a/source/includes/fundamentals/code-examples/Project.cs +++ b/source/includes/fundamentals/code-examples/Project.cs @@ -1,6 +1,4 @@ using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Bson.Serialization.Conventions; using MongoDB.Driver; public class Project