Skip to content

Commit 173895b

Browse files
authored
Docsp-28793: count fundamentals (mongodb#103)
* DOCSP-28793: Count Fundementals * test * test * test * test * test * up through estimated * up through estimated * aggregate * final? * final? * final? * final * api fix * final except error * final * post review * check before and after * post review * error fix * error fix * error fix * error fix * error fix * error fix * examples too long fix * changes requested * changes requested
1 parent 3352ecb commit 173895b

File tree

6 files changed

+313
-6
lines changed

6 files changed

+313
-6
lines changed

source/fundamentals/crud/read-operations.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Read Operations
99

1010
/fundamentals/crud/read-operations/retrieve
1111
/fundamentals/crud/read-operations/specify-query
12+
/fundamentals/crud/read-operations/count
1213

1314
- :ref:`csharp-retrieve`
1415
- :ref:`csharp-specify-query`
16+
- :ref:`csharp-count-documents`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
.. _csharp-count-documents:
2+
3+
===============
4+
Count Documents
5+
===============
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
Overview
14+
--------
15+
16+
In this guide, you can learn how to get an :ref:`accurate
17+
<csharp-accurate-count>` and :ref:`estimated <csharp-estimated-count>` count of
18+
the number of documents in your collection.
19+
20+
Sample Data
21+
~~~~~~~~~~~
22+
23+
The examples in this guide use the following documents in a collection called
24+
``students``:
25+
26+
.. code-block:: json
27+
28+
{ "_id": 1, "name": "Jonathon Howard ", "finalGrade": 87.5 }
29+
{ "_id": 2, "name": "Keisha Freeman", "finalGrade": 12.3 }
30+
{ "_id": 3, "name": "Wei Zhang", "finalGrade": 99.0 }
31+
{ "_id": 4, "name": "Juan Gonzalez", "finalGrade": 85.5 }
32+
{ "_id": 5, "name": "Erik Trout", "finalGrade": 72.3 }
33+
{ "_id": 6, "name": "Demarcus Smith", "finalGrade": 88.8 }
34+
35+
The following ``Student`` class models the documents in this
36+
collection:
37+
38+
.. literalinclude:: /includes/fundamentals/code-examples/CountDocuments.cs
39+
:start-after: start-student-struct
40+
:end-before: end-student-struct
41+
:language: csharp
42+
:dedent:
43+
44+
.. note::
45+
46+
The documents in the ``students`` collection use the camel-case naming
47+
convention. The examples in this guide use a ``ConventionPack``
48+
to deserialize the fields in the collection into Pascal case and map them to
49+
the properties in the ``Student`` class.
50+
51+
To learn more about custom serialization, see
52+
:ref:`csharp-custom-serialization`.
53+
54+
.. _csharp-accurate-count:
55+
56+
Accurate Count
57+
--------------
58+
59+
To count the number of documents that match your :ref:`query filter <csharp-specify-query>`, use the
60+
``CountDocuments()`` method. If you pass an empty query filter, this method
61+
returns the total number of documents in the collection.
62+
63+
Example
64+
~~~~~~~
65+
66+
The following example counts the number of documents where the
67+
value of ``finalGrade`` is less than ``80``:
68+
69+
.. io-code-block::
70+
:copyable: true
71+
72+
.. input::
73+
:language: csharp
74+
75+
var filter = Builders<Student>.Filter.Lt(s => s.FinalGrade, 80.0);
76+
var count = _myColl.CountDocuments(filter);
77+
Console.WriteLine("Number of documents with a final grade less than 80: " + count);
78+
79+
.. output::
80+
:language: none
81+
:visible: false
82+
83+
Number of documents with a final grade less than 80: 2
84+
85+
Modify Behavior
86+
~~~~~~~~~~~~~~~
87+
88+
You can modify the behavior of ``CountDocuments()`` by passing a ``CountOptions`` type as
89+
a parameter. If you don't specify any options, the driver uses default values.
90+
91+
You can set the following properties in a ``CountOptions`` object:
92+
93+
.. list-table::
94+
:widths: 30 70
95+
:header-rows: 1
96+
97+
* - Property
98+
- Description
99+
100+
* - ``Collation``
101+
- | The type of language collation to use when sorting results.
102+
| Default: ``nil``
103+
104+
* - ``Hint``
105+
- | The index to use to scan for documents to count.
106+
| Default: ``nil``
107+
108+
* - ``Limit``
109+
- | The maximum number of documents to count.
110+
| Default: ``0``
111+
112+
* - ``MaxTime``
113+
- | The maximum amount of time that the query can run on the server.
114+
| Default: ``nil``
115+
116+
* - ``Skip``
117+
- | The number of documents to skip before counting.
118+
| Default: ``0``
119+
120+
.. tip::
121+
122+
When you use ``CountDocuments()`` to return the total number of documents in a
123+
collection, MongoDB performs a collection scan. You can avoid a collection scan and
124+
improve the performance of this method by using a hint to take advantage of the built-in index on
125+
the ``_id`` field. Use this technique only when calling ``CountDocuments()``
126+
with an empty query parameter.
127+
128+
.. code-block:: csharp
129+
:emphasize-lines: 1, 2
130+
131+
var filter = Builders<Student>.Filter.Empty;
132+
CountOptions opts = new CountOptions(){Hint = "_id_"};
133+
var count = collection.CountDocuments(filter, opts);
134+
135+
.. _csharp-estimated-count:
136+
137+
Estimated Count
138+
---------------
139+
140+
To estimate the total number of documents in your collection, use the
141+
``EstimatedDocumentCount()`` method.
142+
143+
.. note::
144+
145+
The ``EstimatedDocumentCount()`` method is more efficient than the
146+
``CountDocuments()`` method because it uses the collection's
147+
metadata rather than scanning the entire collection.
148+
149+
Modify Behavior
150+
~~~~~~~~~~~~~~~
151+
152+
You can modify the behavior of ``EstimatedDocumentCount()`` by passing a
153+
``EstimatedDocumentCountOptions`` type as a parameter. If you don't
154+
specify any options, the driver uses default values.
155+
156+
You can set the following properties in a ``EstimatedDocumentCountOptions`` object:
157+
158+
.. list-table::
159+
:widths: 30 70
160+
:header-rows: 1
161+
162+
* - Property
163+
- Description
164+
165+
* - ``MaxTime``
166+
- | The maximum amount of time that the query can run on the server.
167+
| Default: ``nil``
168+
169+
Example
170+
```````
171+
172+
The following example estimates the number of documents in the
173+
``students`` collection:
174+
175+
.. io-code-block::
176+
:copyable: true
177+
178+
.. input::
179+
:language: csharp
180+
181+
var count = _myColl.EstimatedDocumentCount();
182+
Console.WriteLine("Estimated number of documents in the students collection: " + count);
183+
184+
.. output::
185+
:language: none
186+
:visible: false
187+
188+
Estimated number of documents in the students collection: 6
189+
190+
.. _csharp-count-aggregation:
191+
192+
Aggregation
193+
-----------
194+
195+
You can use the ``Count()`` builder method to count the number
196+
of documents in an aggregation pipeline.
197+
198+
Example
199+
~~~~~~~
200+
201+
The following example performs the following actions:
202+
203+
- Specifies a match stage to find documents with a ``FinalGrade`` value
204+
greater than ``80``
205+
- Counts the number of documents that match the criteria
206+
207+
.. io-code-block::
208+
:copyable: true
209+
210+
.. input::
211+
:language: csharp
212+
213+
var filter = Builders<Student>
214+
.Filter.Gt(s => s.FinalGrade, 80);
215+
var result = _myColl.Aggregate().Match(filter).Count();
216+
Console.WriteLine("Number of documents with a final grade more than 80: " + result.First().Count);
217+
218+
.. output::
219+
:language: none
220+
:visible: false
221+
222+
Number of documents with a final grade more than 80: 2
223+
224+
225+
Additional Information
226+
----------------------
227+
228+
To learn more about the operations mentioned, see the following
229+
guides:
230+
231+
- :ref:`csharp-specify-query`
232+
- :ref:`csharp-bson`
233+
- :ref:`csharp-guids`
234+
- :ref:`csharp-builders`
235+
- :ref:`csharp-poco`
236+
237+
API Documentation
238+
~~~~~~~~~~~~~~~~~
239+
240+
To learn more about any of the methods or types discussed in this
241+
guide, see the following API Documentation:
242+
243+
- `CountDocuments() <{+api-root+}/M_MongoDB_Driver_IMongoCollection_1_CountDocuments.htm>`__
244+
- `CountOptions <{+api-root+}/T_MongoDB_Driver_CountOptions.htm>`__
245+
- `EstimatedDocumentCount() <{+api-root+}/M_MongoDB_Driver_MongoCollectionBase_1_EstimatedDocumentCount.htm>`__
246+
- `EstimatedDocumentCountOptions <{+api-root+}/T_MongoDB_Driver_EstimatedDocumentCountOptions.htm>`__

source/fundamentals/crud/read-operations/specify-query.txt

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
Specify a Query
55
===============
66

7-
.. default-domain:: mongodb
8-
97
.. contents:: On this page
108
:local:
119
:backlinks: none

source/fundamentals/data-formats/guid-serialization.txt

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
GUID Serialization
55
==================
66

7-
.. default-domain:: mongodb
8-
97
.. contents:: On this page
108
:local:
119
:backlinks: none

source/fundamentals/data-formats/poco.txt

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
Work with POCOs
55
===============
66

7-
.. default-domain:: mongodb
8-
97
.. contents:: On this page
108
:local:
119
:backlinks: none
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using MongoDB.Bson.Serialization.Conventions;
2+
using MongoDB.Driver;
3+
namespace TestRun.Fundamentals;
4+
public class CountDocuments
5+
{
6+
private static IMongoCollection<Student> _myColl;
7+
private const string MongoConnectionString = "<Your MongoDB URI>";
8+
public static void Main(string[] args)
9+
{
10+
Setup();
11+
InsertSampleData();
12+
13+
// start-accurate-ct
14+
var filter = Builders<Student>.Filter.Lt(s => s.FinalGrade, 80.0);
15+
var count1 = _myColl.CountDocuments(filter);
16+
Console.WriteLine("Number of documents with a final grade less than 80: " + count1);
17+
// end-accurate-ct
18+
19+
// start-est-count
20+
var count2 = _myColl.EstimatedDocumentCount();
21+
Console.WriteLine("Estimated number of documents in the students collection: " + count2);
22+
// end-est-count
23+
24+
// start-agg-count
25+
var matchStage = Builders<Student>
26+
.Filter.Gt(s => s.FinalGrade, 80);
27+
var result = _myColl.Aggregate().Match(matchStage).Count();
28+
Console.WriteLine("Number of documents with a final grade more than 80: "+result.First().Count);
29+
// end-agg-count
30+
31+
_myColl.DeleteMany(Builders<Student>.Filter.Empty);
32+
}
33+
private static void InsertSampleData()
34+
{
35+
var studentList = new List<Student>()
36+
{
37+
new() { Id = 1, Name = "Jonathon Howard", FinalGrade = 87.5 },
38+
new() { Id = 2, Name = "Keisha Freeman", FinalGrade = 12.3 },
39+
new() { Id = 3, Name = "Wei Zhang", FinalGrade = 99.0 },
40+
new() { Id = 4, Name = "Juan Gonzalez", FinalGrade = 85.5 },
41+
new() { Id = 5, Name = "Erik Trout", FinalGrade = 72.3 },
42+
new() { Id = 6, Name = "Demarcus Smith", FinalGrade = 88.8 }
43+
};
44+
var options = new InsertManyOptions() { BypassDocumentValidation = true };
45+
_myColl.InsertMany(studentList, options);
46+
}
47+
private static void Setup()
48+
{
49+
// This allows automapping of the camelCase database fields to our models.
50+
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
51+
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
52+
53+
// Establish the connection to MongoDB and get the restaurants database
54+
var mongoClient = new MongoClient(MongoConnectionString);
55+
var testDB = mongoClient.GetDatabase("test");
56+
_myColl = testDB.GetCollection<Student>("students");
57+
}
58+
}
59+
//start-student-struct
60+
public class Student {
61+
public int Id { get; set; }
62+
public string Name { get; set; }
63+
public double FinalGrade { get; set; }
64+
}
65+
// end-student-struct

0 commit comments

Comments
 (0)