Skip to content

DOCS-3169: Improve $type documentation, factor out BSON type list. #1985

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions source/includes/fact-bson-types.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
======================= ========== ==================
**Type** **Number** **Notes**
----------------------- ---------- ------------------
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 Deprecated.
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with ``-1``.
Max key 127
======================= ========== ==================
8 changes: 6 additions & 2 deletions source/includes/warning-mixing-types.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.. warning::

Storing values of the different types in the same field in a
collection is *strongly* discouraged.
Data models that associate a field name with different data types within a
collection are *strongly* discouraged.

Using such an unstructured model makes it more difficult to reason about the
database, and may lead to programmer error due to the additional logic
involved in working with it.
26 changes: 2 additions & 24 deletions source/reference/bson-types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,7 @@ BSON supports the following data types as values in documents. Each data
type has a corresponding number that can be used with the
:query:`$type` operator to query documents by BSON type.

======================= ==========
**Type** **Number**
----------------------- ----------
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255
Max key 127
======================= ==========
.. include:: /includes/fact-bson-types.rst

To determine a field's type, see :ref:`check-types-in-shell`.

Expand Down Expand Up @@ -152,7 +130,7 @@ milliseconds since the Unix epoch (Jan 1, 1970). This results in a
representable date range of about 290 million years into the past and
future.

The `official BSON specification <http://bsonspec.org/#/specification>`_
The `official BSON specification <http://bsonspec.org/#/specification>`_
refers to the BSON Date type as the *UTC datetime*.

.. versionchanged:: 2.0
Expand Down
147 changes: 65 additions & 82 deletions source/reference/operator/query/type.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,120 +4,103 @@ $type

.. default-domain:: mongodb

Definition
----------

.. query:: $type

*Syntax*: ``{ field: { $type: <BSON type> } }``

:query:`$type` selects the documents where the *value* of the
``field`` is the specified :term:`BSON` type.

Consider the following example:
``field`` is the specified numeric :term:`BSON` type. This is useful when
dealing with highly unstructured data where data types are not predictable.

.. code-block:: javascript
.. include:: /includes/warning-mixing-types.rst

db.inventory.find( { price: { $type : 1 } } )
Behavior
--------

This query will select all documents in the ``inventory`` collection
where the ``price`` field value is a Double.
When applied to arrays, :query:`$type` matches any **inner** element that is of the
specified type. Without :term:`projection` this means that the entire array
will match if **any** element has the right type. With projection, just those
elements of the requested type will be returned in the array.

If the ``field`` holds an array, the :query:`$type` operator
performs the type check against the array elements and **not** the
``field``.
Refer to the following table for the available :term:`BSON` types
and their corresponding numbers.

Consider the following example where the ``tags`` field holds an array:
.. include:: /includes/fact-bson-types.rst

.. code-block:: javascript
``MinKey`` and ``MaxKey`` compare less than and greater than all
other possible :term:`BSON` element values, respectively, and exist
primarily for internal use.

db.inventory.find( { tags: { $type : 4 } } )
To query if a field value is a ``MinKey``, you must use :query:`$type` with
``-1`` as in the following example:

This query will select all documents in the ``inventory`` collection
where the ``tags`` array contains an element that is itself an array.
.. code-block:: javascript

If instead you want to determine whether the ``tags`` field is an
array type, use the :query:`$where` operator:
db.collection.find( { field: { $type: -1 } } );

.. code-block:: javascript

db.inventory.find( { $where : "Array.isArray(this.tags)" } )
Examples
--------

See the :issue:`SERVER-1475` for more information about the
array type.
Querying by Data Type
~~~~~~~~~~~~~~~~~~~~~

Refer to the following table for the available :term:`BSON` types
and their corresponding numbers.
Consider the following query:

======================= ==========
**Type** **Number**
----------------------- ----------
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined (deprecated) 6
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255
Max key 127
======================= ==========
.. code-block:: javascript

``MinKey`` and ``MaxKey`` compare less than and greater than all
other possible :term:`BSON` element values, respectively, and exist
primarily for internal use.
db.inventory.find( { tags: { $type : 2 } } );

.. note::
This will list all documents containing a ``tags`` field that is either a string
or an array holding at least one string. If you only want to list documents where
``tags`` is an array, you could use :query:`$where`:

To query if a field value is a ``MinKey``, you must use the :query:`$type` with
``-1`` as in the following example:
.. code-block:: javascript

.. code-block:: javascript
db.inventory.find( { $where : "Array.isArray(this.tags)" } );

db.collection.find( { field: { $type: -1 } } )
Note that this query involves a table scan and requires
:ref:`Server-side JavaScript <server-side-javascript>` to be enabled.

.. example::
``MinKey`` and ``MaxKey``
~~~~~~~~~~~~~~~~~~~~~~~~~

Consider the following example operation sequence that
demonstrates both type comparison *and* the special ``MinKey``
and ``MaxKey`` values:
The following operation sequence demonstratess both type comparison *and* the
special ``MinKey`` and ``MaxKey`` values:

.. code-block:: javascript
.. code-block:: javascript

db.test.insert( {x : 3});
db.test.insert( {x : 2.9} );
db.test.insert( {x : new Date()} );
db.test.insert( {x : true } );
db.test.insert( {x : MaxKey } )
db.test.insert( {x : MinKey } )
> db.test.insert( [ { x : 3 },
{ x : 2.9 },
{ x : new Date() },
{ x : true },
{ x : MaxKey },
{ x : MinKey } ] );

db.test.find().sort({x:1})
{ "_id" : ObjectId("4b04094b7c65b846e2090112"), "x" : { $minKey : 1 } }
{ "_id" : ObjectId("4b03155dce8de6586fb002c7"), "x" : 2.9 }
{ "_id" : ObjectId("4b03154cce8de6586fb002c6"), "x" : 3 }
{ "_id" : ObjectId("4b031566ce8de6586fb002c9"), "x" : true }
{ "_id" : ObjectId("4b031563ce8de6586fb002c8"), "x" : "Tue Jul 25 2012 18:42:03 GMT-0500 (EST)" }
{ "_id" : ObjectId("4b0409487c65b846e2090111"), "x" : { $maxKey : 1 } }
> db.test.find().sort( { x : 1 } );
{ "_id" : ObjectId("4b04094b7c65b846e2090112"), "x" : { $minKey : 1 } }
{ "_id" : ObjectId("4b03155dce8de6586fb002c7"), "x" : 2.9 }
{ "_id" : ObjectId("4b03154cce8de6586fb002c6"), "x" : 3 }
{ "_id" : ObjectId("4b031566ce8de6586fb002c9"), "x" : true }
{ "_id" : ObjectId("4b031563ce8de6586fb002c8"), "x" : "Tue Jul 25 2012 18:42:03 GMT-0500 (EST)" }
{ "_id" : ObjectId("4b0409487c65b846e2090111"), "x" : { $maxKey : 1 } }

To query for the minimum value of a :term:`shard key` of a
:term:`sharded cluster`, use the following operation when
connected to the :program:`mongos`:
Minimum Shard Key
~~~~~~~~~~~~~~~~~

.. code-block:: javascript
To query for the minimum value of a :term:`shard key` of a
:term:`sharded cluster`, use the following operation when
connected to the :program:`mongos`:

use config
db.chunks.find( { "min.shardKey": { $type: -1 } } )
.. code-block:: javascript

.. include:: /includes/warning-mixing-types.rst
use config
db.chunks.find( { "min.shardKey": { $type: -1 } } )

.. seealso::
.. seealso::

:method:`~db.collection.find()`, :method:`~db.collection.insert()`, :query:`$where`, :term:`BSON`,
:term:`shard key`, :term:`sharded cluster` .
:method:`~db.collection.find()`, :method:`~db.collection.insert()`, :query:`$where`, :term:`BSON`,
:term:`shard key`, :term:`sharded cluster` .