From 977769b76a0146c77b8be66043539747c52b57cb Mon Sep 17 00:00:00 2001 From: kay Date: Wed, 14 Nov 2012 15:01:14 -0500 Subject: [PATCH 1/5] DOCS-658 and DOCS-684 _id, BSON Types, Tutorials --- draft/core/document.txt | 292 ++++++++++++++++-- .../create-auto-incrementing-field.txt | 195 ++++++++++++ source/core/object-id.txt | 10 +- .../fact-document-field-name-restrictions.rst | 3 +- 4 files changed, 475 insertions(+), 25 deletions(-) create mode 100644 draft/tutorial/create-auto-incrementing-field.txt diff --git a/draft/core/document.txt b/draft/core/document.txt index 3e1a764661d..b88f82a61c3 100644 --- a/draft/core/document.txt +++ b/draft/core/document.txt @@ -36,7 +36,7 @@ MongoDB contexts: of :dbcommand:`collStats` command, and - the :doc:`output ` of the - :dbcommand:`serverStatus` command. + :dbcommand:`serverStatus` command. Structure --------- @@ -58,11 +58,11 @@ the following structure: Having support for the full range of :term:`BSON types`, MongoDB documents may contain field and value pairs where the value can be -another document, an array, an array of documents as well -as the basic types such as ``Double``, ``String``, or ``Date``. +another document, an array, an array of documents as well as the basic +types such as ``Double``, ``String``, and ``Date``. See also +:ref:`document-bson-type-considerations`. -Consider the following document that contains values of varying -types: +Consider the following document that contains values of varying types: .. code-block:: javascript @@ -72,8 +72,7 @@ types: birth: new Date('Jun 23, 1912'), death: new Date('Jun 07, 1954'), contribs: [ "Turing machine", "Turing test", "Turingery" ], - views : NumberLong(1250000), - update : Timestamp(1352237167000, 1) + views : NumberLong(1250000) } The document contains the following fields: @@ -89,10 +88,48 @@ The document contains the following fields: - ``views`` that holds a value of *NumberLong* type. -- ``update`` that holds a value of *Timestamp* type. +To determine the type of fields, the :program:`mongo` shell provides: -Types ------ +- The ``instanceof`` operator to check if a field is a specific type. + +- The ``typeof`` operator to return the type of a field. + +Assume the following variable declaration/initialization: + + .. code-block:: javascript + + var mydoc = { + _id: ObjectId("5099803df3f4948bd2f98391"), + name: { first: "Alan", last: "Turing" }, + birth: new Date('Jun 23, 1912'), + death: new Date('Jun 07, 1954'), + contribs: [ "Turing machine", "Turing test", "Turingery" ], + views : NumberLong(1250000), + } + +The following examples demonstrate the use of the ``instanceof`` and +the ``typeof`` operators: + +- The following operation tests whether the ``_id`` field is of type + ``ObjectId``: + + .. code-block:: javascript + + mydoc._id instanceof ObjectId + + The operation returns ``true``. + +- The following operation returns the type of the ``_id`` field: + + .. code-block:: javascript + + typeof mydoc._id + + Rather than the specific ``ObjectId`` type, the operation returns the + generic ``object`` type + +Document Types +-------------- .. _documents-records: @@ -132,7 +169,7 @@ The following document specifies a record in a collection: The document contains the following fields: -- ``_id``, which must hold a unique value. +- ``_id``, which must hold a unique value and is *immutable*. - ``name`` that holds another *document*. This sub-document contains the fields ``first`` and ``last``, which both hold *strings*. @@ -143,6 +180,35 @@ The document contains the following fields: - ``awards`` that holds an *array of documents*. +Take the following considerations for the ``_id`` field: + +- In record documents, the ``_id`` field is always indexed for regular + collections. As such, use ``_id`` values that are roughly in + ascending order. + +- The ``_id`` field may contain values of any BSON data type other than + an array. + +- Although it is common to assign ``ObjectId`` values to ``_id`` + fields, if your objects have a natural unique identifier, consider + using that for the value of ``_id`` to save space and to avoid an + additional index. + +- To set the ``_id`` field to: + + - ``ObjectId``, see the :doc:`ObjectId ` + documentation. + + - A sequence number, refer to the + :doc:`/tutorial/create-auto-incrementing-field` tutorial. + + - UUID, your application must generate the UUID itself. Most UUIDs do + not have a rough ascending order, and thus require additional + caching needs for their index. For efficiency, store the UUID as a + BSON BinData type to reduce the UUID values and their respective + keys in the _id index by half. If, however, you know space and + speed will not be an issue, you can store as a hex string. + .. _documents-query-selectors: Query Specification Documents @@ -196,9 +262,9 @@ for MongoDB to return, remove, or update, as in the following: .. code-block:: javascript - db.csbios.find( { _id: 1 } ) - db.csbios.remove( { _id: { $gt: 3 } } ) - db.csbios.update( { _id: 1, name: { first: 'John', last: 'Backus' } }, + db.bios.find( { _id: 1 } ) + db.bios.remove( { _id: { $gt: 3 } } ) + db.bios.update( { _id: 1, name: { first: 'John', last: 'Backus' } }, ... ) .. _documents-update-actions: @@ -235,12 +301,17 @@ When passed as an argument to the :method:`update() .. code-block:: javascript - db.csbios.update( { _id: 1 }, - { $set: { 'name.middle': 'Warner' }, - $push: { awards: { award: 'IBM Fellow', - year: '1963', - by: 'IBM' } } } - ) + db.bios.update( + { _id: 1 }, + { $set: { 'name.middle': 'Warner' }, + $push: { awards: { + award: 'IBM Fellow', + year: '1963', + by: 'IBM' + } + } + } + ) .. _documents-index: .. _document-index-specification: @@ -279,7 +350,7 @@ the index to create: .. code-block:: javascript - db.csbios.ensureIndex( { _id: 1, 'name.last': 1 } ) + db.bios.ensureIndex( { _id: 1, 'name.last': 1 } ) .. _documents-sort-order: @@ -317,4 +388,181 @@ method, the sort order document sorts the results of the .. code-block:: javascript - db.csbios.find().sort( { 'name.last': 1, 'name.first': 1 } ) + db.bios.find().sort( { 'name.last': 1, 'name.first': 1 } ) + +.. _document-bson-type-considerations: + +MongoDB BSON Type Considerations +-------------------------------- + +The following BSON types require special consideration: + +.. _document-bson-type-object-id: + +ObjectId +~~~~~~~~ + +ObjectId is small, most likely unique, fast to generate, and ordered. +It consists of 12-bytes where the first 4-bytes is the timestamp of the +ObjectId's creation. Refer to the :doc:`ObjectId ` +documentation for more information regarding the type and its benefits. + +.. _document-bson-type-string: + +String +~~~~~~ + +BSON strings are UTF-8. In general, drivers for each programming +language convert from the language's string format to UTF-8 when +serializing and deserializing BSON. In most cases, this means you can +effectively store most international characters in MongoDB strings. In +addition MongoDB :operator:`regex` queries support UTF-8 in the regex +string. + +The :method:`sort() ` on a string uses ``strcmp``; as +such, for internationalization, sort order will be reasonably but not +fully correct. + +.. _document-bson-type-timestamp: + +Timestamp +~~~~~~~~~ + +BSON Timestamp is a special type for *internal* MongoDB use and is +**not** associated with the regular Date type. BSON Timestamp is a 64 bit +value where: + +- the first 32 bits are a ``time_t`` value (seconds since the UTC epoch) + +- the second 32 bits are an incrementing ``ordinal`` for operations + within a given second. + +On a single :program:`mongod` instance, values of type BSON Timestamp +are guaranteed unique. + +In replication, the oplog's ``ts`` field which holds the *OpTime*, or +the operation timestamp, is of type BSON Timestamp. + +Consider the following examples of BSON Timestamp: + +.. note:: + + The BSON Timestamp is for *internal* MongoDB use. The following + examples are only for illustration purposes of the Timestamp + constructor and do **not** represent the typical use of the type. + +- If a BSON Timestamp is constructed using the empty constructor (i.e. + ``new Timestamp()``), the value of the Timestamp depends on the order + of the field in the document: + + - If the BSON Timestamp field is the *first* field of the document or + if ``_id`` field is the first field and the BSON Timestamp field is + the *second* field, the field's Timestamp value will automatically + be populated to a unique value. + + .. code-block:: javascript + + db.bios.insert( { _id: 9, last_updated: new Timestamp() } ) + + The ``last_updated`` field has both its ``time_t`` value + automatically set to ``1352874017000`` and ``ordinal`` value set to + ``1``: + + .. code-block:: javascript + + { "_id" : 9, "last_updated" : Timestamp(1352874017000, 1) } + + - If the BSON Timestamp field is not the *first* field of the + document nor the *second* field with the ``_id`` field as the + first field, the field's Timestamp value will be empty: + + .. code-block:: javascript + + db.bios.insert( { views: NumberLong(0), last_updated: new Timestamp() } ) + + The Timestamp value remains empty with both its ``time_t`` value + set to ``0`` and ``ordinal`` value set to ``0``: + + .. code-block:: javascript + + { + "_id" : ObjectId("50a33daf88d113a4ae94a959"), + "views" : NumberLong(0), + "last_updated" : Timestamp(0, 0) + } + +.. versionchanged:: 2.1 + :program:`mongo` shell displays the Timestamp value with the wrapper: + + .. code-block:: javascript + + Timestamp(, ) + + Earlier versions of the :program:`mongo` shell displays the + Timestamp value as a document: + + .. code-block:: javascript + + { t : , i : } + +.. _document-bson-type-date: + +Date +~~~~ + +BSON Date type is a 64-bit integer that represents the number of +milliseconds since the Unix epoch (Jan 1, 1970). The `official BSON +specification `_ refers to the +BSON Date type as the *UTC datetime*. + +.. versionchanged:: 2.0 BSON Date type is signed. [#unsigned-date]_ + Negative value represent dates before 1970. + +Consider the following examples of BSON Date: + +- Construct a Date using the ``new Date()`` constructor in the + :program:`mongo` shell: + + .. code-block:: javascript + + var mydate1 = new Date() + +- Construct a Date using the ISODate() constructor in the + :program:`mongo` shell: + + .. code-block:: javascript + + var mydate2 = ISODate() + +- Print the Date value as string: + + .. code-block:: javascript + + mydate1.toString() + +- Print the month portion of the Date value, the months start at zero for January : + + .. code-block:: javascript + + mydate1.getMonth() + mydate1.getDate() + +For more Date functions, see +https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date + +.. [#unsigned-date] + + In earlier versions, Date values were incorrectly interpreted as an + *unsigned* integer, adversely affecting sorts, range queries, and + indexes on Date fields. Because indexes are not recreated when + upgrading, please re-index if you created an index on Date values + with earlier versions, and dates before 1970 are relevant to your + application. + +.. note:: + + :program:`mongo` shell provides help for the ``ObjectId()``, + ``BinData()``, and ``HexData()`` shell classes: + + .. code-block:: javascript + + help misc diff --git a/draft/tutorial/create-auto-incrementing-field.txt b/draft/tutorial/create-auto-incrementing-field.txt new file mode 100644 index 00000000000..59f940a59da --- /dev/null +++ b/draft/tutorial/create-auto-incrementing-field.txt @@ -0,0 +1,195 @@ +========================================== +Create an Auto-Incrementing Sequence Field +========================================== + +.. default-domain:: mongodb + +Synopsis +-------- + +In record documents, the field name ``_id`` is reserved for use as a +primary key; its value must be unique in the collection. This document +describes how to create an increasing sequence number to assign to the +``_id`` field. + +.. warning:: + + Generally in MongoDB, you would not use an auto-increment pattern + for the ``_id`` field, or other fields, as this does not scale up + well on large database clusters. Instead you would use an + :term:`ObjectId `. + +Pattern 1: A Counter Collection and Function +-------------------------------------------- + +This pattern maintains a separate ``counters`` collection that tracks +the last number sequence. The ``_id`` field contains the sequence name +and the ``seq`` contains the last value of the sequence. + +1. Insert into the ``counters`` collection, the initial value for the ``userid``: + + .. code-block:: javascript + + db.counters.insert( + { + _id: "userid", + seq: 0 + } + ) + +#. Create a ``getSequence`` function that accepts a ``name`` of the + sequence. The function uses the :method:`findAndModify() + `. + + .. code-block:: javascript + + db.users.insert( + { + _id: getSequence("userid"), + name: "Sarah C." + } + ) + + db.users.insert( + { + _id: getSequence("userid"), + name: "Bob D." + } + ) + + Verify the results with :method:`find() `: + + .. code-block:: javascript + + db.users.find() + + The ``_id`` fields contain incrementing sequence values: + + .. code-block:: javascript + + { + _id : 1, + name : "Sarah C." + } + { + _id : 2, + name : "Bob D." + } + +Pattern 2: Optimistic Loop +-------------------------- + +This pattern uses optimistic concurrency *"insert if not present"* +loop. + +Create a function ``insertDocument`` that performs the *"insert if not +present"* loop. The function acts as a wrapper function around the +``insert() `` method and takes a ``doc`` and a +``targetCollection`` as its arguments. + +Inside the loop: + +1. Query the ``targetCollection`` for the document with the maximum + ``_id`` value. + +#. Determine the next sequence value for ``_id``: + + - Add ``1`` to the returned ``_id`` value if the returned cursor points to a document; else + + - Set to ``1`` if the returned cursor points to no document. + +#. For the ``doc`` to insert, set its ``_id`` field to the calculated sequence value ``seq``. + +#. Insert the ``doc`` into the ``targetCollection``. + +#. If the insert operation errors with duplicate key, loop + again.Otherwise, if the insert operation encounters some other error or + if the operation succeeds, break out of the loop. + + .. code-block:: javascript + + function insertDocument(doc, targetCollection) { + + while( 1 ) { + + var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1); + + var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1; + + doc._id = seq; + + targetCollection.insert(doc); + + var err = db.getLastErrorObj(); + + if( err && err.code ) { + if( err.code == 11000 /* dup key */ ) + continue; + else + print( "unexpected error inserting data: " + tojson( err ) ); + } + + break; + } + } + +#. Use the ``insertDocument()`` function to perform an insert: + + .. code-block:: javascript + + var myCollection = db.users2; + + insertDocument( + { + name: "Grace H." + }, + myCollection + ); + + insertDocument( + { + name: "Ted R." + }, + myCollection + ) + + Verify the results with :method:`find() `: + + .. code-block:: javascript + + db.users2.find() + + The ``_id`` fields contain incrementing sequence values: + + .. code-block:: javascript + + { + _id: 1, + name: "Grace H." + } + { + _id : 2, + "name" : "Ted R." + } + +In cases of extremely high concurrent insert rate on the collection, +there could potentially be a lot of looping. diff --git a/source/core/object-id.txt b/source/core/object-id.txt index 7b308539e6e..a66fd4c9660 100644 --- a/source/core/object-id.txt +++ b/source/core/object-id.txt @@ -25,8 +25,8 @@ additional benefits: - you can access the timestamp of the ObjectId's creation, using the :method:`getTimestamp() ` method. -- Sorting on an ``_id`` field that stores ObjectId values, is - equivalent to sorting by creation time. +- Sorting on an ``_id`` field that stores ObjectId values is equivalent + to sorting by creation time. .. _core-object-id-class: @@ -144,3 +144,9 @@ Consider the example uses of the ``ObjectId()`` class in the .. code-block:: javascript 507f191e810c19729de860ea + +The :program:`mongo` shell provides help for the ``ObjectId()``: + +.. code-block:: javascript + + help misc diff --git a/source/includes/fact-document-field-name-restrictions.rst b/source/includes/fact-document-field-name-restrictions.rst index 9d044fd50f8..d3c445ef3af 100644 --- a/source/includes/fact-document-field-name-restrictions.rst +++ b/source/includes/fact-document-field-name-restrictions.rst @@ -2,7 +2,8 @@ names: - The field name ``_id`` is reserved for use as a primary key; its - value must be unique in the collection + value must be unique in the collection, is immutable, and may be of + any type other than an array. - The field names **cannot** start with the ``$`` character. From 6dd5a2c1bc3c7beb3248a2bbda0a8ede45fb59df Mon Sep 17 00:00:00 2001 From: kay Date: Wed, 14 Nov 2012 19:33:47 -0500 Subject: [PATCH 2/5] DOCS-658 and DOCS-684 edits related to comments --- draft/core/document.txt | 94 +++++++++---------- ... => create-an-auto-incrementing-field.txt} | 86 +++++++++-------- 2 files changed, 96 insertions(+), 84 deletions(-) rename draft/tutorial/{create-auto-incrementing-field.txt => create-an-auto-incrementing-field.txt} (66%) diff --git a/draft/core/document.txt b/draft/core/document.txt index b88f82a61c3..077694237c7 100644 --- a/draft/core/document.txt +++ b/draft/core/document.txt @@ -200,7 +200,7 @@ Take the following considerations for the ``_id`` field: documentation. - A sequence number, refer to the - :doc:`/tutorial/create-auto-incrementing-field` tutorial. + :doc:`/tutorial/create-an-auto-incrementing-field` tutorial. - UUID, your application must generate the UUID itself. Most UUIDs do not have a rough ascending order, and thus require additional @@ -390,12 +390,12 @@ method, the sort order document sorts the results of the db.bios.find().sort( { 'name.last': 1, 'name.first': 1 } ) -.. _document-bson-type-considerations: +.. _document-mongodb-type-considerations: -MongoDB BSON Type Considerations --------------------------------- +MongoDB Type Considerations +--------------------------- -The following BSON types require special consideration: +The following MongoDB types require special consideration: .. _document-bson-type-object-id: @@ -412,16 +412,17 @@ documentation for more information regarding the type and its benefits. String ~~~~~~ -BSON strings are UTF-8. In general, drivers for each programming -language convert from the language's string format to UTF-8 when -serializing and deserializing BSON. In most cases, this means you can -effectively store most international characters in MongoDB strings. In -addition MongoDB :operator:`regex` queries support UTF-8 in the regex -string. +BSON strings are UTF-8. In general, drivers for each programming language +convert from the language's string format to UTF-8 when serializing and +deserializing BSON. In most cases, this means you can effectively store +most international characters in BSON strings. +[#sort-string-internationalization]_ In addition, MongoDB +:operator:`regex` queries support UTF-8 in the regex string. -The :method:`sort() ` on a string uses ``strcmp``; as -such, for internationalization, sort order will be reasonably but not -fully correct. +.. [#sort-string-internationalization] With internalization, + :method:`sort() ` on a string will be reasonably + correct; however, because internally :method:`sort() ` + uses the C++ ``strcmp`` api, the sort order will not be *fully* correct. .. _document-bson-type-timestamp: @@ -429,36 +430,36 @@ Timestamp ~~~~~~~~~ BSON Timestamp is a special type for *internal* MongoDB use and is -**not** associated with the regular Date type. BSON Timestamp is a 64 bit -value where: +**not** associated with the regular :ref:`document-bson-type-date` +type. BSON Timestamp value is a 64 bit value where: -- the first 32 bits are a ``time_t`` value (seconds since the UTC epoch) +- the first 32 bits are a ``time_t`` value (seconds since the Unix epoch) - the second 32 bits are an incrementing ``ordinal`` for operations within a given second. -On a single :program:`mongod` instance, values of type BSON Timestamp -are guaranteed unique. +On a single :program:`mongod` instance, BSON Timestamp values are guaranteed to +be unique. In replication, the oplog's ``ts`` field which holds the *OpTime*, or the operation timestamp, is of type BSON Timestamp. -Consider the following examples of BSON Timestamp: +Consider the following examples of creating BSON Timestamp values: .. note:: - The BSON Timestamp is for *internal* MongoDB use. The following + The BSON Timestamp type is for *internal* MongoDB use. The following examples are only for illustration purposes of the Timestamp constructor and do **not** represent the typical use of the type. -- If a BSON Timestamp is constructed using the empty constructor (i.e. - ``new Timestamp()``), the value of the Timestamp depends on the order - of the field in the document: +- If a BSON Timestamp value is constructed using the empty constructor + (i.e. ``new Timestamp()``), the value depends on the order of the + field in the document: - - If the BSON Timestamp field is the *first* field of the document or - if ``_id`` field is the first field and the BSON Timestamp field is - the *second* field, the field's Timestamp value will automatically - be populated to a unique value. + - If the field with the BSON Timestamp value is the *first* field of + the document or the *second* field if the ``_id`` field is the + first, the Timestamp value will automatically be set to a unique + value. .. code-block:: javascript @@ -472,16 +473,16 @@ Consider the following examples of BSON Timestamp: { "_id" : 9, "last_updated" : Timestamp(1352874017000, 1) } - - If the BSON Timestamp field is not the *first* field of the - document nor the *second* field with the ``_id`` field as the - first field, the field's Timestamp value will be empty: + - If the field with the BSON Timestamp value is not the *first* field + of the document nor the *second* field with the ``_id`` field as + the first field, the Timestamp value will be the empty Timestamp + value with ``time_t`` set to ``0`` and ``ordinal`` set to ``0``: .. code-block:: javascript db.bios.insert( { views: NumberLong(0), last_updated: new Timestamp() } ) - The Timestamp value remains empty with both its ``time_t`` value - set to ``0`` and ``ordinal`` value set to ``0``: + The Timestamp value is the empty Timestamp value (i.e. ``Timestamp(0, 0)`` ): .. code-block:: javascript @@ -498,8 +499,8 @@ Consider the following examples of BSON Timestamp: Timestamp(, ) - Earlier versions of the :program:`mongo` shell displays the - Timestamp value as a document: + Earlier versions of the :program:`mongo` shell display the Timestamp + value as a document: .. code-block:: javascript @@ -510,13 +511,13 @@ Consider the following examples of BSON Timestamp: Date ~~~~ -BSON Date type is a 64-bit integer that represents the number of +BSON Date is a 64-bit integer that represents the number of milliseconds since the Unix epoch (Jan 1, 1970). The `official BSON specification `_ refers to the BSON Date type as the *UTC datetime*. .. versionchanged:: 2.0 BSON Date type is signed. [#unsigned-date]_ - Negative value represent dates before 1970. + Negative values represent dates before 1970. Consider the following examples of BSON Date: @@ -540,21 +541,20 @@ Consider the following examples of BSON Date: mydate1.toString() -- Print the month portion of the Date value, the months start at zero for January : +- Print the month portion of the Date value; months start at zero for January : .. code-block:: javascript - mydate1.getMonth() + mydate1.getDate() + mydate1.getMonth() -For more Date functions, see -https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date +For more Date methods, see `JavaScript Date API +`_ +documentation. -.. [#unsigned-date] - - In earlier versions, Date values were incorrectly interpreted as an - *unsigned* integer, adversely affecting sorts, range queries, and - indexes on Date fields. Because indexes are not recreated when - upgrading, please re-index if you created an index on Date values +.. [#unsigned-date] In earlier versions, Date values were incorrectly + interpreted as an *unsigned* integer, adversely affecting sorts, range + queries, and indexes on Date fields. Because indexes are not recreated + when upgrading, please re-index if you created an index on Date values with earlier versions, and dates before 1970 are relevant to your application. diff --git a/draft/tutorial/create-auto-incrementing-field.txt b/draft/tutorial/create-an-auto-incrementing-field.txt similarity index 66% rename from draft/tutorial/create-auto-incrementing-field.txt rename to draft/tutorial/create-an-auto-incrementing-field.txt index 59f940a59da..1ed7722ab60 100644 --- a/draft/tutorial/create-auto-incrementing-field.txt +++ b/draft/tutorial/create-an-auto-incrementing-field.txt @@ -10,7 +10,11 @@ Synopsis In record documents, the field name ``_id`` is reserved for use as a primary key; its value must be unique in the collection. This document describes how to create an increasing sequence number to assign to the -``_id`` field. +``_id`` field using the following: + +- :ref:`auto-increment-counters-collection` + +- :ref:`auto-increment-optimistic-loop` .. warning:: @@ -19,12 +23,14 @@ describes how to create an increasing sequence number to assign to the well on large database clusters. Instead you would use an :term:`ObjectId `. -Pattern 1: A Counter Collection and Function --------------------------------------------- +.. _auto-increment-counters-collection: + +A Counters Collection +~~~~~~~~~~~~~~~~~~~~~ -This pattern maintains a separate ``counters`` collection that tracks -the last number sequence. The ``_id`` field contains the sequence name -and the ``seq`` contains the last value of the sequence. +A separate ``counters`` collection tracks the last number sequence. The +``_id`` field contains the sequence name and the ``seq`` contains the +last value of the sequence. 1. Insert into the ``counters`` collection, the initial value for the ``userid``: @@ -76,7 +82,7 @@ and the ``seq`` contains the last value of the sequence. } ) - Verify the results with :method:`find() `: + You can verify the results with :method:`find() `: .. code-block:: javascript @@ -95,41 +101,26 @@ and the ``seq`` contains the last value of the sequence. name : "Bob D." } -Pattern 2: Optimistic Loop --------------------------- - -This pattern uses optimistic concurrency *"insert if not present"* -loop. - -Create a function ``insertDocument`` that performs the *"insert if not -present"* loop. The function acts as a wrapper function around the -``insert() `` method and takes a ``doc`` and a -``targetCollection`` as its arguments. - -Inside the loop: - -1. Query the ``targetCollection`` for the document with the maximum - ``_id`` value. - -#. Determine the next sequence value for ``_id``: - - - Add ``1`` to the returned ``_id`` value if the returned cursor points to a document; else - - - Set to ``1`` if the returned cursor points to no document. +.. _auto-increment-optimistic-loop: -#. For the ``doc`` to insert, set its ``_id`` field to the calculated sequence value ``seq``. +Optimistic Loop +~~~~~~~~~~~~~~~ -#. Insert the ``doc`` into the ``targetCollection``. +The Optimistic Loop calculates the incremented ``_id`` value and +attempts to insert a document with the calculated ``_id`` value. If the +insert is successful, end the loop. Otherwise, iterate through the loop +recalculating the ``_id`` value until the insert is successful. -#. If the insert operation errors with duplicate key, loop - again.Otherwise, if the insert operation encounters some other error or - if the operation succeeds, break out of the loop. +#. Create a function named ``insertDocument`` that performs the "insert + if not present" loop. The function wraps the ``insert() + `` method and takes a ``doc`` and a + ``targetCollection`` arguments. .. code-block:: javascript function insertDocument(doc, targetCollection) { - while( 1 ) { + while (1) { var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1); @@ -152,6 +143,27 @@ Inside the loop: } } + The ``while (1)`` loop performs the following actions: + + - Query the ``targetCollection`` for the document with the maximum + ``_id`` value. + + - Determine the next sequence value for ``_id``: + + - Add ``1`` to the returned ``_id`` value if the returned cursor + points to a document; else + + - Set to ``1`` if the returned cursor points to no document. + + - For the ``doc`` to insert, set its ``_id`` field to the calculated + sequence value ``seq``. + + - Insert the ``doc`` into the ``targetCollection``. + + - If the insert operation errors with duplicate key, loop again. + Otherwise, if the insert operation encounters some other error or + if the operation succeeds, break out of the loop. + #. Use the ``insertDocument()`` function to perform an insert: .. code-block:: javascript @@ -172,7 +184,7 @@ Inside the loop: myCollection ) - Verify the results with :method:`find() `: + You can verify the results with :method:`find() `: .. code-block:: javascript @@ -191,5 +203,5 @@ Inside the loop: "name" : "Ted R." } -In cases of extremely high concurrent insert rate on the collection, -there could potentially be a lot of looping. +Extremely high concurrent insert rate on the collection could result in +high iterations of the while-loop. From 3c45489cf9914add8d6fde359f4a071dada015bc Mon Sep 17 00:00:00 2001 From: kay Date: Mon, 19 Nov 2012 16:29:03 -0500 Subject: [PATCH 3/5] DOCS-658 and DOCS-684 BSON types, _id, ObjectId, Tutorials --- draft/core/document.txt | 26 +++++++++++-------- source/tutorial.txt | 1 + .../create-an-auto-incrementing-field.txt | 0 3 files changed, 16 insertions(+), 11 deletions(-) rename {draft => source}/tutorial/create-an-auto-incrementing-field.txt (100%) diff --git a/draft/core/document.txt b/draft/core/document.txt index 077694237c7..e7e27f4e0fa 100644 --- a/draft/core/document.txt +++ b/draft/core/document.txt @@ -136,7 +136,7 @@ Document Types Record Documents ~~~~~~~~~~~~~~~~ -Most documents in MongoDB are records in :term:`collections` which +Most documents in MongoDB are records in :term:`collections ` which store data from users' applications. These documents have the following limitations: @@ -182,9 +182,8 @@ The document contains the following fields: Take the following considerations for the ``_id`` field: -- In record documents, the ``_id`` field is always indexed for regular - collections. As such, use ``_id`` values that are roughly in - ascending order. +- In documents, the ``_id`` field is always indexed for regular + collections. - The ``_id`` field may contain values of any BSON data type other than an array. @@ -202,12 +201,17 @@ Take the following considerations for the ``_id`` field: - A sequence number, refer to the :doc:`/tutorial/create-an-auto-incrementing-field` tutorial. - - UUID, your application must generate the UUID itself. Most UUIDs do - not have a rough ascending order, and thus require additional - caching needs for their index. For efficiency, store the UUID as a - BSON BinData type to reduce the UUID values and their respective - keys in the _id index by half. If, however, you know space and - speed will not be an issue, you can store as a hex string. + - UUID, your application must generate the UUID itself. For + efficiency, store the UUID as a BSON BinData type to reduce the + UUID values and their respective keys in the _id index by half. If, + however, you know space and speed will not be an issue, you can + store as a hex string. + + .. note:: + + Different driver implementations of the UUID + serialization/deserialization logic are not compatible with each + other. .. _documents-query-selectors: @@ -322,7 +326,7 @@ Index Specification Documents Indexes optimize a number of key :doc:`read ` and :doc:`write ` operations. Index specification documents describe the fields to index on during the -:ref:`index creation `. See :doc:`indexes +:doc:`index creation `. See :doc:`indexes ` for an overview of indexes. The index specification documents contain field and value pairs, in diff --git a/source/tutorial.txt b/source/tutorial.txt index 6a32a29bb27..0415bdc8b74 100644 --- a/source/tutorial.txt +++ b/source/tutorial.txt @@ -39,6 +39,7 @@ Development Patterns tutorial/perform-two-phase-commits tutorial/enforce-unique-keys-for-sharded-collections tutorial/aggregation-examples + tutorial/create-an-auto-incrementing-field .. index:: tutorials; application development .. index:: application tutorials diff --git a/draft/tutorial/create-an-auto-incrementing-field.txt b/source/tutorial/create-an-auto-incrementing-field.txt similarity index 100% rename from draft/tutorial/create-an-auto-incrementing-field.txt rename to source/tutorial/create-an-auto-incrementing-field.txt From e7a873976d86c0f259434d05082ce001c8b06d89 Mon Sep 17 00:00:00 2001 From: kay Date: Mon, 26 Nov 2012 12:10:38 -0500 Subject: [PATCH 4/5] DOCS-658 and DOCS-684 implement changes related to Jeff's comments --- draft/core/document.txt | 102 ++++++++---------- .../create-an-auto-incrementing-field.txt | 27 +++-- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/draft/core/document.txt b/draft/core/document.txt index e7e27f4e0fa..ac75fe606c8 100644 --- a/draft/core/document.txt +++ b/draft/core/document.txt @@ -66,14 +66,14 @@ Consider the following document that contains values of varying types: .. code-block:: javascript - { - _id: ObjectId("5099803df3f4948bd2f98391"), - name: { first: "Alan", last: "Turing" }, - birth: new Date('Jun 23, 1912'), - death: new Date('Jun 07, 1954'), - contribs: [ "Turing machine", "Turing test", "Turingery" ], - views : NumberLong(1250000) - } + var mydoc = { + _id: ObjectId("5099803df3f4948bd2f98391"), + name: { first: "Alan", last: "Turing" }, + birth: new Date('Jun 23, 1912'), + death: new Date('Jun 07, 1954'), + contribs: [ "Turing machine", "Turing test", "Turingery" ], + views : NumberLong(1250000) + } The document contains the following fields: @@ -94,21 +94,8 @@ To determine the type of fields, the :program:`mongo` shell provides: - The ``typeof`` operator to return the type of a field. -Assume the following variable declaration/initialization: - - .. code-block:: javascript - - var mydoc = { - _id: ObjectId("5099803df3f4948bd2f98391"), - name: { first: "Alan", last: "Turing" }, - birth: new Date('Jun 23, 1912'), - death: new Date('Jun 07, 1954'), - contribs: [ "Turing machine", "Turing test", "Turingery" ], - views : NumberLong(1250000), - } - -The following examples demonstrate the use of the ``instanceof`` and -the ``typeof`` operators: +Consider the following examples that demonstrate the use of the +``instanceof`` and the ``typeof`` operators: - The following operation tests whether the ``_id`` field is of type ``ObjectId``: @@ -126,7 +113,7 @@ the ``typeof`` operators: typeof mydoc._id Rather than the specific ``ObjectId`` type, the operation returns the - generic ``object`` type + generic ``object`` type. Document Types -------------- @@ -136,10 +123,10 @@ Document Types Record Documents ~~~~~~~~~~~~~~~~ -Most documents in MongoDB are records in :term:`collections ` which -store data from users' applications. +Most documents in MongoDB in :term:`collections ` store +data from users' applications. -These documents have the following limitations: +These documents have the following attributes: - .. include:: /includes/fact-document-max-size.rst @@ -198,7 +185,7 @@ Take the following considerations for the ``_id`` field: - ``ObjectId``, see the :doc:`ObjectId ` documentation. - - A sequence number, refer to the + - A sequence number, see the :doc:`/tutorial/create-an-auto-incrementing-field` tutorial. - UUID, your application must generate the UUID itself. For @@ -206,12 +193,13 @@ Take the following considerations for the ``_id`` field: UUID values and their respective keys in the _id index by half. If, however, you know space and speed will not be an issue, you can store as a hex string. - + .. note:: - + Different driver implementations of the UUID - serialization/deserialization logic are not compatible with each - other. + serialization/deserialization logic may not be fully compatible + with each other. See your specific :api:`driver documentations + <>` for details on the level of interoperability. .. _documents-query-selectors: @@ -291,6 +279,8 @@ Consider the update specification document example: $push: { awards: { award: 'IBM Fellow', year: '1963', by: 'IBM' } + } + } When passed as an argument to the :method:`update() ` method, the update actions document: @@ -305,15 +295,15 @@ When passed as an argument to the :method:`update() .. code-block:: javascript - db.bios.update( + db.bios.update( { _id: 1 }, { $set: { 'name.middle': 'Warner' }, - $push: { awards: { + $push: { awards: { award: 'IBM Fellow', year: '1963', - by: 'IBM' - } - } + by: 'IBM' + } + } } ) @@ -441,7 +431,7 @@ type. BSON Timestamp value is a 64 bit value where: - the second 32 bits are an incrementing ``ordinal`` for operations within a given second. - + On a single :program:`mongod` instance, BSON Timestamp values are guaranteed to be unique. @@ -450,7 +440,7 @@ the operation timestamp, is of type BSON Timestamp. Consider the following examples of creating BSON Timestamp values: -.. note:: +.. note:: The BSON Timestamp type is for *internal* MongoDB use. The following examples are only for illustration purposes of the Timestamp @@ -487,25 +477,25 @@ Consider the following examples of creating BSON Timestamp values: db.bios.insert( { views: NumberLong(0), last_updated: new Timestamp() } ) The Timestamp value is the empty Timestamp value (i.e. ``Timestamp(0, 0)`` ): - + .. code-block:: javascript - + { "_id" : ObjectId("50a33daf88d113a4ae94a959"), "views" : NumberLong(0), "last_updated" : Timestamp(0, 0) } - + .. versionchanged:: 2.1 :program:`mongo` shell displays the Timestamp value with the wrapper: - + .. code-block:: javascript - + Timestamp(, ) - - Earlier versions of the :program:`mongo` shell display the Timestamp - value as a document: - + + Prior to version 2.1, the :program:`mongo` shell display the + Timestamp value as a document: + .. code-block:: javascript { t : , i : } @@ -548,19 +538,19 @@ Consider the following examples of BSON Date: - Print the month portion of the Date value; months start at zero for January : .. code-block:: javascript - + mydate1.getMonth() For more Date methods, see `JavaScript Date API -`_ +`_ documentation. -.. [#unsigned-date] In earlier versions, Date values were incorrectly - interpreted as an *unsigned* integer, adversely affecting sorts, range - queries, and indexes on Date fields. Because indexes are not recreated - when upgrading, please re-index if you created an index on Date values - with earlier versions, and dates before 1970 are relevant to your - application. +.. [#unsigned-date] Prior to version 2.0, Date values were incorrectly + interpreted as *unsigned* integers, adversely affecting sorts, range + queries, and indexes on Date fields. Because indexes are not + recreated when upgrading, please re-index if you created an index on + Date values with earlier versions, and dates before 1970 are + relevant to your application. .. note:: diff --git a/source/tutorial/create-an-auto-incrementing-field.txt b/source/tutorial/create-an-auto-incrementing-field.txt index 1ed7722ab60..f98524bbb77 100644 --- a/source/tutorial/create-an-auto-incrementing-field.txt +++ b/source/tutorial/create-an-auto-incrementing-field.txt @@ -7,8 +7,8 @@ Create an Auto-Incrementing Sequence Field Synopsis -------- -In record documents, the field name ``_id`` is reserved for use as a -primary key; its value must be unique in the collection. This document +In documents, the field name ``_id`` is reserved for use as a primary +key; its value must be unique in the collection. This document describes how to create an increasing sequence number to assign to the ``_id`` field using the following: @@ -28,9 +28,9 @@ describes how to create an increasing sequence number to assign to the A Counters Collection ~~~~~~~~~~~~~~~~~~~~~ -A separate ``counters`` collection tracks the last number sequence. The -``_id`` field contains the sequence name and the ``seq`` contains the -last value of the sequence. +A separate ``counters`` collection tracks the *last* number sequence +used. The ``_id`` field contains the sequence name and the ``seq`` +contains the last value of the sequence. 1. Insert into the ``counters`` collection, the initial value for the ``userid``: @@ -43,41 +43,40 @@ last value of the sequence. } ) -#. Create a ``getSequence`` function that accepts a ``name`` of the +#. Create a ``getNextSequence`` function that accepts a ``name`` of the sequence. The function uses the :method:`findAndModify() `. .. code-block:: javascript db.users.insert( { - _id: getSequence("userid"), + _id: getNextSequence("userid"), name: "Sarah C." } ) db.users.insert( { - _id: getSequence("userid"), + _id: getNextSequence("userid"), name: "Bob D." } ) @@ -203,5 +202,5 @@ recalculating the ``_id`` value until the insert is successful. "name" : "Ted R." } -Extremely high concurrent insert rate on the collection could result in -high iterations of the while-loop. +High concurrent insert rate on the collection could result in high +iterations of the while-loop. From 6b1bf7125c9afbca876906b09b7c539788711ba4 Mon Sep 17 00:00:00 2001 From: kay Date: Mon, 26 Nov 2012 14:06:58 -0500 Subject: [PATCH 5/5] DOCS-658 and DOCS-684 remove extraneous specification from headings --- draft/core/document.txt | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/draft/core/document.txt b/draft/core/document.txt index ac75fe606c8..e3ea9118e1d 100644 --- a/draft/core/document.txt +++ b/draft/core/document.txt @@ -203,18 +203,18 @@ Take the following considerations for the ``_id`` field: .. _documents-query-selectors: -Query Specification Documents -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Query Documents +~~~~~~~~~~~~~~~ -Query selector documents specify the conditions that determine which -records to select for read, update, and delete operations. You can use -field and value expressions to specify the equality condition and -:doc:`query operator ` expressions to specify -additional conditions. Refer to :doc:`read `, -:doc:`update `, and :doc:`delete -` pages for more examples. +Query documents specify the conditions that determine which records to +select for read, update, and delete operations. You can use field and +value expressions to specify the equality condition and :doc:`query +operator ` expressions to specify additional +conditions. Refer to :doc:`read `, :doc:`update +`, and :doc:`delete ` pages +for more examples. -Consider the following examples of query selector documents: +Consider the following examples of query documents: - The following document specifies the query criteria where ``_id`` is equal to ``1``: @@ -261,17 +261,17 @@ for MongoDB to return, remove, or update, as in the following: .. _documents-update-actions: -Update Specification Documents -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Update Documents +~~~~~~~~~~~~~~~~ -The update action documents specify the data modifications to perform -during an :method:`update() ` operation to -modify existing records in a collection. You can use :ref:`update -operators ` to specify the exact actions to perform -on the document fields. See the :ref:`update operators -` page for the available update operators and syntax. +The update documents specify the data modifications to perform during +an :method:`update() ` operation to modify +existing records in a collection. You can use :ref:`update operators +` to specify the exact actions to perform on the +document fields. See the :ref:`update operators ` +page for the available update operators and syntax. -Consider the update specification document example: +Consider the update document example: .. code-block:: javascript @@ -310,16 +310,16 @@ When passed as an argument to the :method:`update() .. _documents-index: .. _document-index-specification: -Index Specification Documents -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Index Documents +~~~~~~~~~~~~~~~ Indexes optimize a number of key :doc:`read ` -and :doc:`write ` operations. Index -specification documents describe the fields to index on during the -:doc:`index creation `. See :doc:`indexes +and :doc:`write ` operations. Index documents +describe the fields to index on during the :doc:`index creation +`. See :doc:`indexes ` for an overview of indexes. -The index specification documents contain field and value pairs, in +The index documents contain field and value pairs, in the following form: .. code-block:: javascript @@ -348,8 +348,8 @@ the index to create: .. _documents-sort-order: -Sort Order Specification Documents -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sort Order Documents +~~~~~~~~~~~~~~~~~~~~ The sort order documents specify the order of documents that a :method:`query() ` returns. Pass sort order @@ -357,7 +357,7 @@ specification documents as an argument to the :method:`sort() ` method. See the :method:`sort() ` page for more information on sorting. -The sort order specifications contain field and value pairs, in the following +The sort order documents contain field and value pairs, in the following form: .. code-block:: javascript