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