@@ -103,3 +103,78 @@ The results consist of those documents that do not contain the field
103
103
{ a: 2, c: 5 }
104
104
{ a: 4 }
105
105
{ c: 6 }
106
+
107
+ Use a Sparse Index to Improve ``$exists`` Performance
108
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109
+
110
+ The following scenario is not optimal because all of the collection's
111
+ documents are examined:
112
+
113
+ - You use a query to retrieve or count documents, and
114
+ - use ``field: { $exists: true }``, and
115
+ - the ``field`` has a non-:ref:`sparse index <index-type-sparse>` or
116
+ does not have an index.
117
+
118
+ To improve performance, create a :ref:`sparse index <index-type-sparse>`
119
+ on the ``field`` as shown in the following scenario:
120
+
121
+ #. Create a ``stockSales`` collection:
122
+
123
+ .. code-block:: javascript
124
+
125
+ db.stockSales.insertMany( [
126
+ { _id: 0, symbol: "ABC", auditDate: new Date( "2021-05-18T16:12:23Z" ) },
127
+ { _id: 1, symbol: "ABC", auditDate: new Date( "2021-04-21T11:34:45Z" ) },
128
+ { _id: 2, symbol: "DEF", auditDate: new Date( "2021-02-24T15:11:32Z" ) },
129
+ { _id: 3, symbol: "DEF", auditDate: null },
130
+ { _id: 4, symbol: "DEF", auditDate: new Date( "2021-07-13T18:32:54Z" ) },
131
+ { _id: 5, symbol: "XYZ" }
132
+ ] )
133
+
134
+ The document with an ``_id`` of:
135
+
136
+ - ``3`` has a null ``auditDate`` value.
137
+ - ``5`` is missing the ``auditDate`` value.
138
+
139
+ #. Create a :ref:`sparse index <index-type-sparse>` on the
140
+ ``auditDate`` field:
141
+
142
+ .. code-block:: javascript
143
+
144
+ db.getCollection( "stockSales" ).createIndex(
145
+ { auditDate: 1 },
146
+ { name: "auditDateSparseIndex", sparse: true }
147
+ )
148
+
149
+ #. The following example counts the documents where the ``auditDate``
150
+ field has a value (including null) and uses the :ref:`sparse index
151
+ <index-type-sparse>`:
152
+
153
+ .. code-block:: javascript
154
+
155
+ db.stockSales.countDocuments( { auditDate: { $exists: true } } )
156
+
157
+ The example returns 5. The document that is missing the ``auditDate``
158
+ value is not counted.
159
+
160
+ .. tip::
161
+
162
+ If you only need documents where the ``field`` has a non-null value,
163
+ you:
164
+
165
+ - Can use ``$ne: null`` instead of ``$exists: true``.
166
+ - Do not need a :ref:`sparse index <index-type-sparse>` on the
167
+ ``field``.
168
+
169
+ For example, using the ``stockSales`` collection:
170
+
171
+ .. code-block:: javascript
172
+
173
+ db.stockSales.countDocuments( { auditDate: { $ne: null } } )
174
+
175
+ The example returns 4. Documents that are missing the ``auditDate``
176
+ value or have a null ``auditDate`` value are not counted.
177
+
178
+ .. seealso::
179
+
180
+ :doc:`/tutorial/query-for-null-fields`
0 commit comments