|
2 | 2 | eval
|
3 | 3 | ====
|
4 | 4 |
|
| 5 | +.. Edits to this page should be carried over to the method db.eval.txt |
| 6 | + file. |
| 7 | + |
5 | 8 | .. default-domain:: mongodb
|
6 | 9 |
|
7 | 10 | .. dbcommand:: eval
|
8 | 11 |
|
9 |
| - The :dbcommand:`eval` command evaluates JavaScript functions |
10 |
| - on the database server. Consider the following (trivial) example: |
| 12 | + The :dbcommand:`eval` command evaluates JavaScript functions on the |
| 13 | + database server and has the following form: |
| 14 | + |
| 15 | + .. code-block:: none |
| 16 | + |
| 17 | + { |
| 18 | + eval: <function>, |
| 19 | + args: [ <arg1>, <arg2> ... ], |
| 20 | + nolock: <boolean> |
| 21 | + } |
| 22 | + |
| 23 | + The command contains the following fields: |
| 24 | + |
| 25 | + :field JavaScript function: |
| 26 | + A JavaScript function to evaluate. The function may |
| 27 | + accept no arguments, as in the following example: |
| 28 | + |
| 29 | + .. code-block:: javascript |
| 30 | + |
| 31 | + function () { |
| 32 | + |
| 33 | + ... |
| 34 | + |
| 35 | + } |
| 36 | + |
| 37 | + The function can also accept arguments, as in the following example: |
| 38 | + |
| 39 | + .. code-block:: javascript |
| 40 | + |
| 41 | + function (arg1, arg2) { |
| 42 | + |
| 43 | + ... |
| 44 | + } |
| 45 | + |
| 46 | + If you specify arguments, you must include the corresponding |
| 47 | + ``args`` field in the command. |
| 48 | + |
| 49 | + :field Array args: |
| 50 | + An array of corresponding arguments to the ``function``. Omit |
| 51 | + ``args`` if the ``function`` does not take arguments. |
| 52 | + |
| 53 | + :field Boolean nolock: |
| 54 | + Optional. Specifies whether to disable the write lock. By |
| 55 | + default, :dbcommand:`eval` takes a write lock. There are |
| 56 | + circumstances where the :dbcommand:`eval` executes a strictly |
| 57 | + read-only operation that does not need to block other |
| 58 | + operations. If ``nolock`` is ``true``, the |
| 59 | + :dbcommand:`eval` does not take a write lock. |
| 60 | + |
| 61 | + .. warning:: |
| 62 | + |
| 63 | + Do not disable the write lock if the function may modify |
| 64 | + the contents of the database in any way. |
| 65 | + |
| 66 | + Consider the following example which uses :dbcommand:`eval` to |
| 67 | + perform an increment and calculate the average on the server: |
11 | 68 |
|
12 | 69 | .. code-block:: javascript
|
13 | 70 |
|
14 |
| - { eval: function() { return 3+3 } } |
| 71 | + db.runCommand( { |
| 72 | + eval: function(name, incAmount) { |
| 73 | + var doc = db.myCollection.findOne( { name : name } ); |
| 74 | + |
| 75 | + doc = doc || { name : name , num : 0 , total : 0 , avg : 0 }; |
| 76 | + |
| 77 | + doc.num++; |
| 78 | + doc.total += incAmount; |
| 79 | + doc.avg = doc.total / doc.num; |
| 80 | + |
| 81 | + db.myCollection.save( doc ); |
| 82 | + return doc; |
| 83 | + }, |
| 84 | + args: [ "eliot", 5 ] |
| 85 | + } |
| 86 | + ); |
15 | 87 |
|
16 |
| - The shell also provides a helper method, so you can express the |
17 |
| - above as follows: |
| 88 | + The ``db`` in the function refers to the current database. |
| 89 | + |
| 90 | + The shell also provides a helper method :method:`db.eval()`, so you |
| 91 | + can express the above as follows: |
18 | 92 |
|
19 | 93 | .. code-block:: javascript
|
20 | 94 |
|
21 |
| - db.eval( function() { return 3+3 } ); |
| 95 | + db.eval( function(name, incAmount) { |
| 96 | + var doc = db.myCollection.findOne( { name : name } ); |
| 97 | + |
| 98 | + doc = doc || { name : name , num : 0 , total : 0 , avg : 0 }; |
22 | 99 |
|
23 |
| - The shell's JavaScript interpreter evaluates functions entered |
24 |
| - directly into the shell. If you want to use the server's |
25 |
| - interpreter, you must run :dbcommand:`eval`. |
| 100 | + doc.num++; |
| 101 | + doc.total += incAmount; |
| 102 | + doc.avg = doc.total / doc.num; |
| 103 | + |
| 104 | + db.myCollection.save( doc ); |
| 105 | + return doc; |
| 106 | + }, |
| 107 | + "eliot", 5 ); |
26 | 108 |
|
27 |
| - Be aware of following behaviors and limitations: |
| 109 | + You cannot pass the ``nolock`` flag to the :method:`db.eval()` |
| 110 | + in the :program:`mongo` shell. |
28 | 111 |
|
29 |
| - - :dbcommand:`eval` does not work in :term:`sharded <sharding>` |
30 |
| - environments. |
| 112 | + If you want to use the server's interpreter, you must run |
| 113 | + :dbcommand:`eval`. Otherwise, the :program:`mongo` shell's |
| 114 | + JavaScript interpreter evaluates functions entered directly into the |
| 115 | + shell. |
31 | 116 |
|
32 |
| - - The ``eval`` operation take a write lock by default. This means |
33 |
| - that writes to database aren't permitted while it's running. You |
34 |
| - can, however, disable the lock by setting the ``nolock`` flag to |
35 |
| - ``true``. For example: |
| 117 | + If an error occurs, :dbcommand:`eval` throws an exception. Consider |
| 118 | + the following invalid function that uses the variable ``x`` without |
| 119 | + declaring it as an argument: |
| 120 | + |
| 121 | + .. code-block:: javascript |
36 | 122 |
|
37 |
| - .. code-block:: javascript |
| 123 | + db.runCommand( |
| 124 | + { |
| 125 | + eval: function() { return x + x; }, |
| 126 | + args: [3] |
| 127 | + } |
| 128 | + ) |
| 129 | + |
| 130 | + The statement will result in the following exception: |
| 131 | + |
| 132 | + .. code-block:: javascript |
38 | 133 |
|
39 |
| - { eval: function() { return 3+3 }, nolock: true } |
| 134 | + { |
| 135 | + "errno" : -3, |
| 136 | + "errmsg" : "invoke failed: JS Error: ReferenceError: x is not defined nofile_b:1", |
| 137 | + "ok" : 0 |
| 138 | + } |
40 | 139 |
|
41 |
| - Using :method:`db.runCommand()` helper, in the :program:`mongo` |
42 |
| - shell, this command would resemble: |
| 140 | + .. warning:: |
43 | 141 |
|
44 |
| - .. code-block:: javascript |
| 142 | + - The :dbcommand:`eval` operation takes a write lock by default. |
| 143 | + This means that other read and write operations to the database |
| 144 | + are blocked while :dbcommand:`eval` is running. You can, |
| 145 | + however, disable the lock by setting the ``nolock`` flag to |
| 146 | + ``true`` if the ``eval`` performs a strictly read-only |
| 147 | + operation. |
45 | 148 |
|
46 |
| - db.runCommand( { eval: function() { return 3+3 }, nolock: true } ) |
| 149 | + - :dbcommand:`eval` also takes a JavaScript lock. |
47 | 150 |
|
48 |
| - .. warning:: |
| 151 | + - Do not use :dbcommand:`eval` for long running operations as |
| 152 | + :dbcommand:`eval` blocks all other operations. Consider using |
| 153 | + :doc:`other server side code execution options |
| 154 | + </applications/server-side-code-execution>`. |
49 | 155 |
|
50 |
| - Do not disable the write lock if the operation may modify the |
51 |
| - contents of the database in anyway. |
| 156 | + - You can not use :dbcommand:`eval` with :term:`sharded |
| 157 | + <sharding>` data. In general, you should avoid using |
| 158 | + :dbcommand:`eval` in :term:`sharded cluster`; nevertheless, it |
| 159 | + is possible to use :dbcommand:`eval` with non-sharded |
| 160 | + collections and databases stored in a :term:`sharded cluster`. |
52 | 161 |
|
53 |
| - You cannot pass the ``nolock`` option to :method:`db.eval()` in |
54 |
| - the :program:`mongo` shell. |
| 162 | + .. seealso:: |
55 | 163 |
|
56 |
| - There are some circumstances where the :method:`db.eval()` |
57 |
| - implements a strictly-read only operation that need not block |
58 |
| - other operations when disabling the write lock may be useful. Use |
59 |
| - this functionality with extreme caution. |
| 164 | + :doc:`/applications/server-side-code-execution` |
0 commit comments