From 217796dd334b371a928c107138b2abaabef0febc Mon Sep 17 00:00:00 2001 From: Steve Renaker Date: Thu, 20 Apr 2017 16:58:06 -0700 Subject: [PATCH] DOCS-7854: Document how to check if a field itself is an array --- source/reference/operator/query/type.txt | 102 +++++++++++++++++++++-- 1 file changed, 95 insertions(+), 7 deletions(-) diff --git a/source/reference/operator/query/type.txt b/source/reference/operator/query/type.txt index 4dd6292ebfe..2abdebaaab5 100644 --- a/source/reference/operator/query/type.txt +++ b/source/reference/operator/query/type.txt @@ -320,17 +320,74 @@ The ``SensorReading`` collection contains the following documents: 24, 23 ] + }, + { + "_id": 3, + "readings": [ + 22, + 24, + [] + ] + }, + { + "_id": 4, + "readings": [] + }, + { + "_id": 5, + "readings": 24 } - -The following query returns any document where ``readings`` has an -element of :term:`BSON` type ``array``; i.e. the :query:`$type` does -not check if ``readings`` itself is an array: + +The following query returns any document in which the ``readings`` +field contains an element of :term:`BSON` type ``array``. Note that +the :query:`$type` query filter does not detect whether the ``readings`` +field itself is an array. .. code-block:: javascript db.SensorReading.find( { "readings" : { $type: "array" } } ) -This returns the following document: +The above query returns the following documents: + +.. code-block:: javascript + + { + "_id": 1, + "readings": [ + 25, + 23, + [ "Warn: High Temp!", 55 ], + [ "ERROR: SYSTEM SHUTDOWN!", 66 ] + ] + }, + { + "_id": 3, + "readings": [ + 22, + 24, + [] + ] + } + +In the documents with ``_id : 1`` and ``_id : 3``, the ``readings`` +field contains at least one element which is an array, while the +other documents do not. + +As seen above, the :query:`$type` operator looks inside a given field +to see whether any of its elements are arrays, but it does not consider +whether the given field is itself an array. To do that, use the +following query: + +.. code-block:: javascript + + db.SensorReading.find( { "readings" : { $elemMatch: { $exists: true } } } ) + +:query:`$elemMatch` searches an array for a given element, and +:query:`$exists` determines whether a given field exists. Used +together, they return ``true`` if the specified field is of +:term:`BSON` type ``array``. + +The above query returns the following documents: .. code-block:: javascript @@ -342,10 +399,41 @@ This returns the following document: [ "Warn: High Temp!", 55 ], [ "ERROR: SYSTEM SHUTDOWN!", 66 ] ] + }, + { + "_id": 2, + "readings": [ + 25, + 25, + 24, + 23 + ] + }, + { + "_id": 3, + "readings": [ + 22, + 24, + [] + ] } -The document with ``_id : 1`` has at least one element in ``readings`` -that is an ``array``, whereas the document with ``_id : 2`` does *not*. +To find all documents in the collection in which the ``readings`` +field is an array, either empty or non-empty, the following query +uses an :query:`$or` operator: + +.. code-block:: javascript + + db.SensorReading.find( { + $or: [ + { "readings": { $elemMatch: { $exists: true } } }, + { "readings": [] } + ] + } ) + +The above query returns the first four documents in the collection and +excludes the one with ``_id : 5``, in which the ``readings`` field is +an integer instead of an array. Additional Information ----------------------