diff --git a/source/release-notes/2.4.txt b/source/release-notes/2.4.txt index 281285e6136..cad271660e5 100644 --- a/source/release-notes/2.4.txt +++ b/source/release-notes/2.4.txt @@ -617,12 +617,13 @@ accordance with all privileges granted to this user for all databases. .. see:: :doc:`MongoDB Security Practices and Procedures `. -Default JavaScript Engine Switched to v8 from SpiderMonkey +Default JavaScript Engine Switched to V8 from SpiderMonkey ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The default JavaScript engine used throughout MongoDB, for the :program:`mongo` shell, :dbcommand:`mapReduce`, :operator:`$where`, -and :dbcommand:`eval` is now v8. +:dbcommand:`group`, and :dbcommand:`eval` is now `V8 +`_. .. data:: serverBuildInfo.interpreterVersion @@ -637,6 +638,489 @@ and :dbcommand:`eval` is now v8. reports which JavaScript interpreter this :program:`mongo` shell uses. +.. DOCS-981 + +The primary impacts of the switch to V8 are: + +- concurrency improvements, +- modernized JavaScript implementation, and +- removal of non-standard Spidermonkey features. + +Concurrency Improvements +```````````````````````` + +Previously, MongoDB operations that required the JavaScript interpreter +had to acquire a lock, and a single :program:`mongod` could only run a +single JavaScript operation at a time. The switch to V8 improves +concurrency by allowing each JavaScript operation to run on a separate +core. + +Modernized JavaScript Implementation (ES5) +`````````````````````````````````````````` + +The 5th edition of `ECMAscript +`_, +abbreviated as ES5, adds many new language features, such as: + +- standardized `JSON + `_, + +- `strict mode + `_, + +- `function.bind() + `_, + +- `array extensions + `_, + +- getters/setters and much more. + +With V8, MongoDB supports the latest standardized version of JavaScript +with the following exceptions. The following features do not work as expected +on documents returned from MongoDB queries: + +- ``Object.seal()``, + +- ``Object.freeze()``, + +- ``Object.preventExtensions()``, and + +- enumerable properties. + +Removal of Non-standard Spidermonkey Features +````````````````````````````````````````````` + +V8 does **not** support the following *non-standard* `Spidermonkey +`_ JavaScript +extensions. + +E4X Extensions +^^^^^^^^^^^^^^ + +V8 does not support the *non-standard* `E4X +`_ extensions. E4X +provides a native `XML +`_ +object to the JavaScript language and adds the syntax for embedding +literal XML documents in JavaScript code. + +You need to use alternative XML processing if you used any of the +following constructors/methods: + +- ``XML()`` + +- ``Namespace()`` + +- ``QName()`` + +- ``XMLList()`` + +- ``isXMLName()`` + +Destructuring Assignment +^^^^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support the non-standard destructuring assignments. +Destructuring assignment "extract[s] data from arrays or objects using +a syntax that mirrors the construction of array and object literals." - +`Mozilla docs +`_ + +.. example:: + + The following destructuring assignment is **invalid** with V8 and + throws a ``SyntaxError``: + + .. code-block:: javascript + + original = [4, 8, 15]; + var [b, ,c] = a; // <== destructuring assignment + print(b) // 4 + print(c) // 15 + +``Iterator()``, ``StopIteration()``, and Generators +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support `Iterator(), StopIteration(), and generators +`_. + +``InternalError()`` +^^^^^^^^^^^^^^^^^^^ + +V8 does not support ``InternalError()``. Use ``Error()`` instead. + +``for each...in`` Construct +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support the use of `for each...in +`_ +construct. Use ``for (var x in y)`` construct +instead. + +.. example:: + + The following ``for each (var x in y)`` construct is **invalid** + with V8: + + .. code-block:: javascript + + var o = { name: 'MongoDB', version: 2.4 }; + + for each (var value in o) { + print(value); + } + + Instead, in version 2.4, you can use the ``for (var x in y)`` + construct: + + .. code-block:: javascript + + var o = { name: 'MongoDB', version: 2.4 }; + + for (var prop in o) { + var value = o[prop]; + print(value); + } + + You can also use the array *instance* method ``forEach()`` with the + ES5 method ``Object.keys()``: + + .. code-block:: javascript + + Object.keys(o).forEach(function (key) { + var value = o[key]; + print(value); + }); + +Array comprehensions +^^^^^^^^^^^^^^^^^^^^ + +V8 does not support `Array comprehensions +`_. + +Use other methods such as the ``Array`` instance methods ``map()``, +``filter()``, or ``forEach()``. + +.. example:: + + With V8, the following array comprehension is **invalid**: + + .. code-block:: javascript + + var a = { w: 1, x: 2, y: 3, z: 4 } + + var arr = [i * i for each (i in a) if (i > 2)] + printjson(arr) + + Instead, you can implement using the ``Array`` *instance* method + ``forEach()`` and the ES5 method ``Object.keys()`` : + + .. code-block:: javascript + + var a = { w: 1, x: 2, y: 3, z: 4 } + + var arr = []; + Object.keys(a).forEach(function (key) { + var val = a[key]; + if (val > 2) arr.push(val * val); + }) + printjson(arr) + + .. note:: + + The new logic uses the ``Array`` *instance* method ``forEach()`` and + not the *generic* method ``Array.forEach()``; V8 does **not** + support ``Array`` *generic* methods. See :ref:`array-generics` for + more information. + +Multiple Catch Blocks +^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support multiple ``catch`` blocks and will throw a +``SyntaxError``. + +.. example:: + + The following multiple catch blocks is **invalid** with V8 and will + throw ``"SyntaxError: Unexpected token if"``: + + .. code-block:: javascript + + try { + something() + } catch (err if err instanceof SomeError) { + print('some error') + } catch (err) { + print('standard error') + } + +Conditional Function Definitions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +V8 will produce different outcomes than Spidermonkey with `conditional +function definitions +`_. + +.. example:: + + The following conditional function definition produces different + outcomes in Spidermonkey versus V8: + + .. code-block:: javascript + + function test () { + if (false) { + function go () {}; + } + print(typeof go) + } + + With Spidermonkey, the conditional function outputs ``undefined``, + whereas with V8, the conditional function outputs ``function``. + + If your code defines functions this way, it is highly recommended + that you refactor the code. The following example refactors the + conditional function definition to work in both Spidermonkey and V8. + + .. code-block:: javascript + + function test () { + var go; + if (false) { + go = function () {} + } + print(typeof go) + } + + The refactored code outputs ``undefined`` in both Spidermonkey and V8. + +.. note:: + + ECMAscript prohibits conditional function definitions. To force V8 + to throw an ``Error``, `enable strict mode + `_. + + .. code-block:: javascript + + function test () { + 'use strict'; + + if (false) { + function go () {} + } + } + + The JavaScript code throws ``SyntaxError: In strict mode code, + functions can only be declared at top level or immediately within + another function.`` + +String Generic Methods +^^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support `String generics +`_. +String generics are a set of methods on the ``String`` class that +mirror instance methods. + +.. example:: + + The following use of the generic method + ``String.toLowerCase()`` is **invalid** with V8: + + .. code-block:: javascript + + var name = 'MongoDB'; + + var lower = String.toLowerCase(name); + + With V8, use the ``String`` instance method ``toLowerCase()`` available + through an *instance* of the ``String`` class instead: + + .. code-block:: javascript + + var name = 'MongoDB'; + + var lower = name.toLowerCase(); + print(name + ' becomes ' + lower); + +With V8, use the ``String`` *instance* methods instead of following +*generic* methods: + +.. list-table:: + + * - ``String.charAt()`` + - ``String.quote()`` + - ``String.toLocaleLowerCase()`` + + * - ``String.charCodeAt()`` + - ``String.replace()`` + - ``String.toLocaleUpperCase()`` + + * - ``String.concat()`` + - ``String.search()`` + - ``String.toLowerCase()`` + + * - ``String.endsWith()`` + - ``String.slice()`` + - ``String.toUpperCase()`` + + * - ``String.indexOf()`` + - ``String.split()`` + - ``String.trim()`` + + * - ``String.lastIndexOf()`` + - ``String.startsWith()`` + - ``String.trimLeft()`` + + * - ``String.localeCompare()`` + - ``String.substr()`` + - ``String.trimRight()`` + + * - ``String.match()`` + - ``String.substring()`` + - + +.. _array-generics: + +Array Generics +^^^^^^^^^^^^^^ + +V8 does not support `Array generics +`_. +Array generics are a set of methods on the ``Array`` class that mirror +instance methods. + +.. example:: + + The following use of the generic method ``Array.every()`` is + **invalid** with V8: + + .. code-block:: javascript + + var arr = [4, 8, 15, 16, 23, 42]; + + function isEven (val) { + return 0 === val % 2; + } + + var allEven = Array.every(arr, isEven); + print(allEven); + + With V8, use the ``Array`` instance method ``every()`` available through + an *instance* of the ``Array`` class instead: + + .. code-block:: javascript + + var allEven = arr.every(isEven); + print(allEven); + +With V8, use the ``Array`` *instance* methods instead of the following +*generic* methods: + +.. list-table:: + + * - ``Array.concat()`` + - ``Array.lastIndexOf()`` + - ``Array.slice()`` + + * - ``Array.every()`` + - ``Array.map()`` + - ``Array.some()`` + + * - ``Array.filter()`` + - ``Array.pop()`` + - ``Array.sort()`` + + * - ``Array.forEach()`` + - ``Array.push()`` + - ``Array.splice()`` + + * - ``Array.indexOf()`` + - ``Array.reverse()`` + - ``Array.unshift()`` + + * - ``Array.join()`` + - ``Array.shift()`` + - + +Array Instance Method ``toSource()`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +V8 does not support the ``Array`` instance method `toSource() +`_. +Use the ``Array`` instance method ``toString()`` instead. + +``uneval()`` +^^^^^^^^^^^^ + +V8 does not support the non-standard method ``uneval()``. Use the +standardized `JSON.stringify() +`_ +method instead. + +``Map-Reduce`` and ``$where`` +`````````````````````````````````````` + +In MongoDB 2.4, :doc:`map-reduce operations +`, the :command:`group` command, and +:operator:`$where` operator expressions **cannot** access certain +global functions or properties, such as ``db``, that are available in +the :program:`mongo` shell. + +When upgrading to MongoDB 2.4, you will need to refactor your code if +your :doc:`map-reduce operations `, +:command:`group` commands, or :operator:`$where` operator expressions +include any global shell functions or properties that are no longer +available, such as ``db``. + +The following shell functions and properties **are available** to +:doc:`map-reduce operations `, the +:command:`group` command, and :operator:`$where` operator expressions +in MongoDB 2.4: + +.. list-table:: + :header-rows: 1 + + * - Available Properties + - Available Functions + - + + * - + | ``args`` + | ``MaxKey`` + | ``MinKey`` + + - + | ``assert()`` + | ``BinData()`` + | ``DBPointer()`` + | ``DBRef()`` + | ``doassert()`` + | ``emit()`` + | ``gc()`` + | ``HexData()`` + | ``hex_md5()`` + | ``isNumber()`` + | ``isObject()`` + | ``ISODate()`` + | ``isString()`` + + - + | ``Map()`` + | ``MD5()`` + | ``NumberInt()`` + | ``NumberLong()`` + | ``ObjectId()`` + | ``print()`` + | ``sleep()`` + | ``Timestamp()`` + | ``tojson()`` + | ``tojsononeline()`` + | ``tojsonObject()`` + | ``UUID()`` + | ``version()`` + .. DOCS-752 New Geospatial Indexes with GeoJSON and Improved Spherical Geometry @@ -685,12 +1169,12 @@ the following GeoJSON shapes: - ``Polygon``, as in the following: - .. code-block:: javascript + .. code-block:: javascript - { - "type": "Polygon", - "coordinates": [ [ [ 40, 5 ], [ 40, 6 ], [ 41, 6 ], [ 41, 5 ], [ 40, 5 ] ] ] - } + { + "type": "Polygon", + "coordinates": [ [ [ 40, 5 ], [ 40, 6 ], [ 41, 6 ], [ 41, 5 ], [ 40, 5 ] ] ] + } To query ``2dsphere`` indexes, all current geospatial :ref:`query operators ` with an additional