Skip to content

Commit 91b46dc

Browse files
authored
backport (#12351)
1 parent 4ad3420 commit 91b46dc

File tree

12 files changed

+721
-142
lines changed

12 files changed

+721
-142
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using MongoDB.Bson;
2+
using MongoDB.Driver;
3+
4+
namespace Projection;
5+
6+
public class ElemMatchExamples
7+
{
8+
static string _uri = Environment.GetEnvironmentVariable("MONGODB_URI");
9+
10+
static IMongoCollection<School> schoolsCollection = new MongoClient(_uri)
11+
.GetDatabase("example")
12+
.GetCollection<School>("schools");
13+
14+
public static List<BsonDocument> ZipSearch()
15+
{
16+
// start zipSearch
17+
var results = schoolsCollection
18+
.Find(s => s.ZipCode == "63109")
19+
.Project(Builders<School>.Projection.ElemMatch(
20+
field: school => school.Students,
21+
filter: student => student.School == 102
22+
)
23+
).ToList();
24+
// end zipSearch
25+
26+
return results;
27+
}
28+
29+
public static List<BsonDocument> ZipMultipleSearch()
30+
{
31+
// start zipMultipleSearch
32+
var results = schoolsCollection
33+
.Find(s => s.ZipCode == "63109")
34+
.Project(Builders<School>.Projection.ElemMatch(
35+
field: school => school.Students,
36+
filter: student => (student.School == 102) && (student.Age > 10)
37+
)
38+
).ToList();
39+
// end zipMultipleSearch
40+
41+
return results;
42+
}
43+
44+
public static List<BsonDocument> ZipAthleticsIncomplete()
45+
{
46+
// start zipAthleticsIncomplete
47+
var results = schoolsCollection
48+
.Find(s => s.ZipCode == "63109")
49+
.Project(Builders<School>.Projection.ElemMatch(
50+
"athletics",
51+
Builders<School>.Filter.Eq("athletics", "basketball"))
52+
).ToList();
53+
// end zipAthleticsIncomplete
54+
55+
return results;
56+
}
57+
58+
public static List<BsonDocument> ZipAthletics()
59+
{
60+
// start zipAthletics
61+
var results = schoolsCollection
62+
.Find(s => s.ZipCode == "63109")
63+
.Project(Builders<School>.Projection.ElemMatch(
64+
field: "athletics",
65+
filter: Builders<School>.Filter.Eq("$eq", "basketball"))
66+
).ToList();
67+
// end zipAthletics
68+
69+
return results;
70+
}
71+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public class School
2+
{
3+
public string Id { get; set; }
4+
5+
[BsonElement("zipcode")]
6+
public string ZipCode { get; set; }
7+
8+
public Student[] Students { get; set; }
9+
10+
public string[] Athletics { get; set; }
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class Student
2+
{
3+
public string Id { get; set; }
4+
5+
public string Name { get; set; }
6+
7+
public int School { get; set; }
8+
9+
public int Age { get; set; }
10+
}

content/manual/manual/source/reference/operator/projection/elemMatch.txt

Lines changed: 148 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ Restrictions
4444
- You cannot specify a :query:`$text` query operator in an
4545
:projection:`$elemMatch`.
4646

47-
4847
Examples
4948
--------
5049

@@ -54,8 +53,7 @@ assumes a collection ``schools`` with the following documents:
5453
.. code-block:: javascript
5554
:copyable: true
5655

57-
db.school.insertMany( [
58-
{
56+
{
5957
_id: 1,
6058
zipcode: "63109",
6159
students: [
@@ -90,30 +88,72 @@ assumes a collection ``schools`` with the following documents:
9088
{ name: "ruth", school: 102, age: 16 },
9189
]
9290
}
93-
] )
9491

92+
.. tabs-drivers::
93+
94+
.. tab:: MongoDB Shell
95+
:tabid: shell
96+
97+
.. tab:: C#
98+
:tabid: csharp
99+
100+
You can model these documents by using the following C# classes:
95101

102+
.. literalinclude:: /includes/driver-examples/projection/School.cs
103+
:language: csharp
104+
105+
.. literalinclude:: /includes/driver-examples/projection/Student.cs
106+
:language: csharp
96107

97108
Zipcode Search
98109
~~~~~~~~~~~~~~
99110

100-
The following :method:`~db.collection.find()` operation
101-
queries for all documents where the value of the ``zipcode``
102-
field is ``63109``. The :projection:`$elemMatch` projection
103-
returns only the **first** matching element of the ``students``
104-
array where the ``school`` field has a value of ``102``:
111+
.. tabs-selector:: drivers
105112

106-
.. code-block:: javascript
107-
:copyable: true
113+
.. tabs-drivers::
114+
115+
.. tab:: MongoDB Shell
116+
:tabid: shell
108117

109-
db.schools.find( { zipcode: "63109" },
110-
{ students: { $elemMatch: { school: 102 } } } )
118+
The following :method:`~db.collection.find()` operation
119+
queries for all documents where the value of the ``zipcode``
120+
field is ``"63109"``. The :projection:`$elemMatch` projection
121+
returns only the **first** matching element of the ``students``
122+
array where the ``school`` field has a value of ``102``:
111123

112-
The operation returns the following documents that have ``zipcode``
113-
equal to ``63109`` and projects the ``students`` array using
124+
.. code-block:: javascript
125+
:copyable: true
126+
127+
db.schools.find( { zipcode: "63109" },
128+
{ students: { $elemMatch: { school: 102 } } } )
129+
130+
.. tab:: C#
131+
:tabid: csharp
132+
133+
To perform an ``$elemMatch`` projection when using the .NET/C# driver, call the
134+
``ElemMatch()`` method on the projection builder. Pass the name of the array field
135+
to project and the filter to apply to the array elements.
136+
137+
The following code example finds all documents in which the value of the ``Zipcode``
138+
field is ``"63109"``. For each matching document, the projection returns the
139+
following fields:
140+
141+
- ``Id``
142+
- The first element of the ``Students`` array in which the value of the nested
143+
``School`` field has the value ``102``
144+
145+
.. literalinclude:: /includes/driver-examples/projection/ElemMatchExamples.cs
146+
:language: csharp
147+
:start-after: // start zipSearch
148+
:end-before: // end zipSearch
149+
:dedent: 8
150+
151+
The operation returns the following documents that have a ``zipcode`` value of
152+
``"63109"`` and projects the ``students`` array using
114153
:projection:`$elemMatch`:
115154

116155
.. code-block:: javascript
156+
:copyable: false
117157

118158
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
119159
{ "_id" : 3 }
@@ -134,24 +174,47 @@ equal to ``63109`` and projects the ``students`` array using
134174
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135175

136176
The :projection:`$elemMatch` projection can specify criteria on multiple
137-
fields:
177+
fields.
138178

139-
The following :method:`~db.collection.find()` operation
140-
queries for all documents where the value of the ``zipcode``
141-
field is ``63109``. The projection includes the **first**
142-
matching element of the ``students`` array where the ``school``
143-
field has a value of ``102`` **and** the ``age`` field is greater
144-
than ``10``:
179+
.. tabs-drivers::
145180

146-
.. code-block:: javascript
147-
:copyable: true
181+
.. tab:: MongoDB Shell
182+
:tabid: shell
183+
184+
The following :method:`~db.collection.find()` operation
185+
queries for all documents where the value of the ``zipcode``
186+
field is ``"63109"``. The projection includes the **first**
187+
matching element of the ``students`` array where the ``school``
188+
field has a value of ``102`` **and** the ``age`` field is greater
189+
than ``10``:
148190

149-
db.schools.find( { zipcode: "63109" },
150-
{ students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )
191+
.. code-block:: javascript
192+
:copyable: true
151193

152-
The operation returns the three documents that have ``zipcode`` equal to ``63109``:
194+
db.schools.find( { zipcode: "63109" },
195+
{ students: { $elemMatch: { school: 102, age: { $gt: 10} } } } )
196+
197+
.. tab:: C#
198+
:tabid: csharp
199+
200+
The following code example finds all documents in which the value of the ``Zipcode``
201+
field is ``"63109"``. For each matching document, the projection returns the following fields:
202+
203+
- ``Id``
204+
- The first element of the ``Students`` array in which the value of the nested
205+
``School`` field has the value ``102`` and the ``Age`` field has a value greater than
206+
``10``
207+
208+
.. literalinclude:: /includes/driver-examples/projection/ElemMatchExamples.cs
209+
:language: csharp
210+
:start-after: // start zipMultipleSearch
211+
:end-before: // end zipMultipleSearch
212+
:dedent: 8
213+
214+
The operation returns the three documents that have a ``zipcode`` value of ``"63109"``:
153215

154216
.. code-block:: javascript
217+
:copyable: false
155218

156219
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] }
157220
{ "_id" : 3 }
@@ -161,43 +224,81 @@ The document with ``_id`` equal to ``3`` does not contain the ``students`` field
161224
since no array element matched the :projection:`$elemMatch` criteria.
162225

163226
The argument to :projection:`$elemMatch` matches elements of the array that
164-
``$elemMatch`` is projecting. If you specify an equality with a field
227+
``$elemMatch`` is projecting. If you specify an equality with a field
165228
name to ``$elemMatch``, it attempts to match objects within the array.
166229
For example, ``$elemMatch`` attempts to match objects, instead of scalar
167230
values, within the array for the following in the projection:
168231

169-
.. code-block:: javascript
170-
:copyable: true
232+
.. tabs-drivers::
171233

172-
db.schools.find( { zipcode: "63109" },
173-
{ athletics: { $elemMatch: { athletics: "basketball" } } })
234+
.. tab:: MongoDB Shell
235+
:tabid: shell
174236

175-
To match scalar values, use the equality operator along with the scalar
176-
value that you want to match (``{$eq: <scalar value>}``). For example,
177-
the following :method:`~db.collection.find()` operation queries for all
178-
documents where the value of the ``zipcode`` field is ``63109``. The
179-
projection includes the matching element of the ``athletics`` array
180-
where the value is ``basketball``:
237+
.. code-block:: javascript
181238

182-
.. code-block:: javascript
183-
:copyable: true
239+
db.schools.find( { zipcode: "63109" },
240+
{ athletics: { $elemMatch: { athletics: "basketball" } } })
241+
242+
.. tab:: C#
243+
:tabid: csharp
244+
245+
.. literalinclude:: /includes/driver-examples/projection/ElemMatchExamples.cs
246+
:language: csharp
247+
:start-after: // start zipAthleticsIncomplete
248+
:end-before: // end zipAthleticsIncomplete
249+
:dedent: 8
250+
251+
The preceding examples return the documents that have a ``zipcode`` value of
252+
``"63109"``, but these documents include only the ``_id`` field because the projection
253+
operation found no matching elements.
254+
255+
.. tabs-drivers::
256+
257+
.. tab:: MongoDB Shell
258+
:tabid: shell
259+
260+
To match scalar values, use the equality operator along with the scalar
261+
value that you want to match (``{$eq: <scalar value>}``). For example,
262+
the following :method:`~db.collection.find()` operation queries for all
263+
documents where the value of the ``zipcode`` field is ``"63109"``. The
264+
projection includes the matching element of the ``athletics`` array
265+
where the value is ``basketball``:
266+
267+
.. code-block:: javascript
268+
:copyable: true
269+
270+
db.schools.find( { zipcode: "63109" },
271+
{ athletics: { $elemMatch: { $eq: "basketball" } } })
272+
273+
.. tab:: C#
274+
:tabid: csharp
275+
276+
To perform an ``$elemMatch`` operation against scalar values in an array when using
277+
the .NET/C# driver, call the ``ElemMatch()`` method
278+
on the projection builder. Pass the name of the array field to project and an
279+
equality filter for the field ``"$eq"`` and the value you want to compare against.
184280

185-
db.schools.find( { zipcode: "63109" },
186-
{ athletics: { $elemMatch: { $eq: "basketball" } } })
281+
.. literalinclude:: /includes/driver-examples/projection/ElemMatchExamples.cs
282+
:language: csharp
283+
:start-after: // start zipAthletics
284+
:end-before: // end zipAthletics
285+
:dedent: 8
187286

188-
The operation returns the three documents that have ``zipcode`` equal to
189-
``63109``:
287+
The operation returns the three documents that have ``zipcode`` value of
288+
``"63109"``. The returned documents include the ``_id`` field and matching
289+
elements of the ``athletics`` array, if any.
190290

191291
.. code-block:: javascript
292+
:copyable: false
192293

193294
[
194-
{ _id : 1 },
295+
{ _id: 1 },
195296
{ _id: 3, athletics: [ 'basketball' ] },
196-
{ _id : 4 }
297+
{ _id: 4 }
197298
]
198299

199300
The document with ``_id`` equal to ``3`` is the only document that
200-
matched the :projection:`$elemMatch` criteria.
301+
matched the :projection:`$elemMatch` criteria.
201302

202303
.. seealso::
203304

0 commit comments

Comments
 (0)