diff --git a/source/reference/operator/query/exists.txt b/source/reference/operator/query/exists.txt index 829da4bb218..cce8d4cddec 100644 --- a/source/reference/operator/query/exists.txt +++ b/source/reference/operator/query/exists.txt @@ -113,7 +113,77 @@ The results consist of those documents that do not contain the field .. include:: /includes/extracts/4.2-changes-type-0.rst +Use a Sparse Index to Improve ``$exists`` Performance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following scenario is not optimal because all of the collection's +documents are examined: + +- You use a query to retrieve or count documents, and +- use ``field: { $exists: true }``, and +- the ``field`` has a non-:ref:`sparse index ` or + does not have an index. + +To improve performance, create a :ref:`sparse index ` +on the ``field`` as shown in the following scenario: + +#. Create a ``stockSales`` collection: + + .. code-block:: javascript + + db.stockSales.insertMany( [ + { _id: 0, symbol: "ABC", auditDate: new Date( "2021-05-18T16:12:23Z" ) }, + { _id: 1, symbol: "ABC", auditDate: new Date( "2021-04-21T11:34:45Z" ) }, + { _id: 2, symbol: "DEF", auditDate: new Date( "2021-02-24T15:11:32Z" ) }, + { _id: 3, symbol: "DEF", auditDate: null }, + { _id: 4, symbol: "DEF", auditDate: new Date( "2021-07-13T18:32:54Z" ) }, + { _id: 5, symbol: "XYZ" } + ] ) + + The document with an ``_id`` of: + + - ``3`` has a null ``auditDate`` value. + - ``5`` is missing the ``auditDate`` value. + +#. Create a :ref:`sparse index ` on the + ``auditDate`` field: + + .. code-block:: javascript + + db.getCollection( "stockSales" ).createIndex( + { auditDate: 1 }, + { name: "auditDateSparseIndex", sparse: true } + ) + +#. The following example counts the documents where the ``auditDate`` + field has a value (including null) and uses the :ref:`sparse index + `: + + .. code-block:: javascript + + db.stockSales.countDocuments( { auditDate: { $exists: true } } ) + + The example returns 5. The document that is missing the ``auditDate`` + value is not counted. + +.. tip:: + + If you only need documents where the ``field`` has a non-null value, + you: + + - Can use ``$ne: null`` instead of ``$exists: true``. + - Do not need a :ref:`sparse index ` on the + ``field``. + + For example, using the ``stockSales`` collection: + + .. code-block:: javascript + + db.stockSales.countDocuments( { auditDate: { $ne: null } } ) + + The example returns 4. Documents that are missing the ``auditDate`` + value or have a null ``auditDate`` value are not counted. + .. seealso:: :doc:`/tutorial/query-for-null-fields` -