Skip to content

DOCS-11142: prefer $expr over $where #3210

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

Merged
merged 1 commit into from
Jan 31, 2018
Merged
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
76 changes: 48 additions & 28 deletions source/reference/operator/query/where.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ $where
.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:depth: 2
:class: singlecol

Definition
----------

.. query:: $where

Use the :query:`$where` operator to pass either a string
Expand All @@ -20,6 +23,14 @@ $where
collection. Reference the document in the JavaScript expression or
function using either ``this`` or ``obj`` .

.. important::
.. versionchanged:: 3.6
The :query:`$expr` operator allows the
use of :ref:`aggregation expressions <aggregation-framework>`
within the query language. :query:`$expr` is faster than
:query:`$where` because it does not execute JavaScript and should
be preferred where possible.

Behavior
--------

Expand Down Expand Up @@ -66,34 +77,43 @@ following performance advantages:
- The non\-:query:`$where` query statements may use an
:term:`index`.

Examples
~~~~~~~~

Consider the following examples:

.. code-block:: javascript

db.myCollection.find( { $where: "this.credits == this.debits" } );
db.myCollection.find( { $where: "obj.credits == obj.debits" } );

db.myCollection.find( { $where: function() { return (this.credits == this.debits) } } );
db.myCollection.find( { $where: function() { return obj.credits == obj.debits; } } );

Additionally, if the query consists only of the :query:`$where`
operator, you can pass in just the JavaScript expression or
JavaScript functions, as in the following examples:

.. code-block:: javascript

db.myCollection.find( "this.credits == this.debits || this.credits > this.debits" );

db.myCollection.find( function() { return (this.credits == this.debits || this.credits > this.debits ) } );
Example
-------

You can include both the standard MongoDB operators and the
:query:`$where` operator in your query, as in the following
examples:
Consider the following documents in the ``users`` collection:

.. code-block:: javascript

db.myCollection.find( { active: true, $where: "this.credits - this.debits < 0" } );
db.myCollection.find( { active: true, $where: function() { return obj.credits - obj.debits < 0; } } );
{
_id: 12378,
name: "Steve",
username: "steveisawesome",
first_login: "2017-01-01"
}
{
_id: 2,
name: "Anya",
username: "anya",
first_login: "2001-02-02"
}

The following example uses :query:`$where` and the ``hex_md5()``
JavaScript function to compare the value of the ``name`` field to an
MD5 hash and returns any matching document.

.. code-block:: sh

db.foo.find( { $where: function() {
return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994")
} } );

The operation returns the following result:

.. code-block:: sh

{
"_id" : 2,
"name" : "Anya",
"username" : "anya",
"first_login" : "2001-02-02"
}