From a6449a7b2c97cf669b887cb04f6cd61911e874c2 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 9 Sep 2011 05:45:56 -0700 Subject: [PATCH] Updates to documentation in prep for 0.5 --- docs/guide/defining-documents.rst | 78 +++++++----- docs/guide/document-instances.rst | 10 +- docs/guide/gridfs.rst | 1 + docs/guide/installing.rst | 20 +-- docs/guide/querying.rst | 202 +++++++++++++++++------------- docs/guide/signals.rst | 4 +- docs/index.rst | 39 +++++- docs/upgrade.rst | 27 ++-- mongoengine/queryset.py | 14 ++- 9 files changed, 240 insertions(+), 155 deletions(-) diff --git a/docs/guide/defining-documents.rst b/docs/guide/defining-documents.rst index a524520c..00a7d090 100644 --- a/docs/guide/defining-documents.rst +++ b/docs/guide/defining-documents.rst @@ -4,14 +4,14 @@ Defining documents In MongoDB, a **document** is roughly equivalent to a **row** in an RDBMS. When working with relational databases, rows are stored in **tables**, which have a strict **schema** that the rows follow. MongoDB stores documents in -**collections** rather than tables - the principle difference is that no schema -is enforced at a database level. +**collections** rather than tables - the principle difference is that no schema +is enforced at a database level. Defining a document's schema ============================ MongoEngine allows you to define schemata for documents as this helps to reduce coding errors, and allows for utility methods to be defined on fields which may -be present. +be present. To define a schema for a document, create a class that inherits from :class:`~mongoengine.Document`. Fields are specified by adding **field @@ -19,7 +19,7 @@ objects** as class attributes to the document class:: from mongoengine import * import datetime - + class Page(Document): title = StringField(max_length=200, required=True) date_modified = DateTimeField(default=datetime.datetime.now) @@ -31,31 +31,34 @@ By default, fields are not required. To make a field mandatory, set the validation constraints available (such as :attr:`max_length` in the example above). Fields may also take default values, which will be used if a value is not provided. Default values may optionally be a callable, which will be called -to retrieve the value (such as in the above example). The field types available +to retrieve the value (such as in the above example). The field types available are as follows: * :class:`~mongoengine.StringField` * :class:`~mongoengine.URLField` +* :class:`~mongoengine.EmailField` * :class:`~mongoengine.IntField` * :class:`~mongoengine.FloatField` * :class:`~mongoengine.DecimalField` * :class:`~mongoengine.DateTimeField` +* :class:`~mongoengine.ComplexDateTimeField` * :class:`~mongoengine.ListField` +* :class:`~mongoengine.SortedListField` * :class:`~mongoengine.DictField` +* :class:`~mongoengine.MapField` * :class:`~mongoengine.ObjectIdField` -* :class:`~mongoengine.EmbeddedDocumentField` * :class:`~mongoengine.ReferenceField` * :class:`~mongoengine.GenericReferenceField` +* :class:`~mongoengine.EmbeddedDocumentField` * :class:`~mongoengine.BooleanField` * :class:`~mongoengine.FileField` -* :class:`~mongoengine.EmailField` -* :class:`~mongoengine.SortedListField` * :class:`~mongoengine.BinaryField` * :class:`~mongoengine.GeoPointField` +* :class:`~mongoengine.SequenceField` Field arguments --------------- -Each field type can be customized by keyword arguments. The following keyword +Each field type can be customized by keyword arguments. The following keyword arguments can be set on all fields: :attr:`db_field` (Default: None) @@ -74,7 +77,7 @@ arguments can be set on all fields: The definion of default parameters follow `the general rules on Python `__, - which means that some care should be taken when dealing with default mutable objects + which means that some care should be taken when dealing with default mutable objects (like in :class:`~mongoengine.ListField` or :class:`~mongoengine.DictField`):: class ExampleFirst(Document): @@ -89,7 +92,7 @@ arguments can be set on all fields: # This can make an .append call to add values to the default (and all the following objects), # instead to just an object values = ListField(IntField(), default=[1,2,3]) - + :attr:`unique` (Default: False) When True, no documents in the collection will have the same value for this @@ -104,7 +107,13 @@ arguments can be set on all fields: :attr:`choices` (Default: None) An iterable of choices to which the value of this field should be limited. - + +:attr:`help_text` (Default: None) + Optional help text to output with the field - used by form libraries + +:attr:`verbose` (Default: None) + Optional human-readable name for the field - used by form libraries + List fields ----------- @@ -121,7 +130,7 @@ Embedded documents MongoDB has the ability to embed documents within other documents. Schemata may be defined for these embedded documents, just as they may be for regular documents. To create an embedded document, just define a document as usual, but -inherit from :class:`~mongoengine.EmbeddedDocument` rather than +inherit from :class:`~mongoengine.EmbeddedDocument` rather than :class:`~mongoengine.Document`:: class Comment(EmbeddedDocument): @@ -144,7 +153,7 @@ Often, an embedded document may be used instead of a dictionary -- generally this is recommended as dictionaries don't support validation or custom field types. However, sometimes you will not know the structure of what you want to store; in this situation a :class:`~mongoengine.DictField` is appropriate:: - + class SurveyResponse(Document): date = DateTimeField() user = ReferenceField(User) @@ -152,16 +161,19 @@ store; in this situation a :class:`~mongoengine.DictField` is appropriate:: survey_response = SurveyResponse(date=datetime.now(), user=request.user) response_form = ResponseForm(request.POST) - survey_response.answers = response_form.cleaned_data() + survey_response.answers = response_form.cleaned_data() survey_response.save() +Dictionaries can store complex data, other dictionaries, lists, references to +other objects, so are the most flexible field type available. + Reference fields ---------------- References may be stored to other documents in the database using the :class:`~mongoengine.ReferenceField`. Pass in another document class as the first argument to the constructor, then simply assign document objects to the field:: - + class User(Document): name = StringField() @@ -235,13 +247,13 @@ Its value can take any of the following constants: in-memory, by the MongoEngine module, it is of the upmost importance that the module that declares the relationship is loaded **BEFORE** the delete is invoked. - + If, for example, the :class:`Employee` object lives in the :mod:`payroll` app, and the :class:`ProfilePage` in the :mod:`people` app, it is extremely important that the :mod:`people` app is loaded before any employee is removed, because otherwise, MongoEngine could never know this relationship exists. - + In Django, be sure to put all apps that have such delete rule declarations in their :file:`models.py` in the :const:`INSTALLED_APPS` tuple. @@ -250,15 +262,15 @@ Generic reference fields '''''''''''''''''''''''' A second kind of reference field also exists, :class:`~mongoengine.GenericReferenceField`. This allows you to reference any -kind of :class:`~mongoengine.Document`, and hence doesn't take a +kind of :class:`~mongoengine.Document`, and hence doesn't take a :class:`~mongoengine.Document` subclass as a constructor argument:: class Link(Document): url = StringField() - + class Post(Document): title = StringField() - + class Bookmark(Document): bookmark_object = GenericReferenceField() @@ -272,9 +284,10 @@ kind of :class:`~mongoengine.Document`, and hence doesn't take a Bookmark(bookmark_object=post).save() .. note:: + Using :class:`~mongoengine.GenericReferenceField`\ s is slightly less efficient than the standard :class:`~mongoengine.ReferenceField`\ s, so if - you will only be referencing one document type, prefer the standard + you will only be referencing one document type, prefer the standard :class:`~mongoengine.ReferenceField`. Uniqueness constraints @@ -282,7 +295,7 @@ Uniqueness constraints MongoEngine allows you to specify that a field should be unique across a collection by providing ``unique=True`` to a :class:`~mongoengine.Field`\ 's constructor. If you try to save a document that has the same value for a unique -field as a document that is already in the database, a +field as a document that is already in the database, a :class:`~mongoengine.OperationError` will be raised. You may also specify multi-field uniqueness constraints by using :attr:`unique_with`, which may be either a single field name, or a list or tuple of field names:: @@ -294,14 +307,14 @@ either a single field name, or a list or tuple of field names:: Skipping Document validation on save ------------------------------------ -You can also skip the whole document validation process by setting -``validate=False`` when caling the :meth:`~mongoengine.document.Document.save` +You can also skip the whole document validation process by setting +``validate=False`` when caling the :meth:`~mongoengine.document.Document.save` method:: class Recipient(Document): name = StringField() email = EmailField() - + recipient = Recipient(name='admin', email='root@localhost') recipient.save() # will raise a ValidationError while recipient.save(validate=False) # won't @@ -329,7 +342,7 @@ A :class:`~mongoengine.Document` may use a **Capped Collection** by specifying stored in the collection, and :attr:`max_size` is the maximum size of the collection in bytes. If :attr:`max_size` is not specified and :attr:`max_documents` is, :attr:`max_size` defaults to 10000000 bytes (10MB). -The following example shows a :class:`Log` document that will be limited to +The following example shows a :class:`Log` document that will be limited to 1000 entries and 2MB of disk space:: class Log(Document): @@ -369,9 +382,10 @@ If a dictionary is passed then the following options are available: Whether the index should be sparse. .. note:: - Geospatial indexes will be automatically created for all + + Geospatial indexes will be automatically created for all :class:`~mongoengine.GeoPointField`\ s - + Ordering ======== A default ordering can be specified for your @@ -393,7 +407,7 @@ subsequent calls to :meth:`~mongoengine.queryset.QuerySet.order_by`. :: blog_post_1 = BlogPost(title="Blog Post #1") blog_post_1.published_date = datetime(2010, 1, 5, 0, 0 ,0) - blog_post_2 = BlogPost(title="Blog Post #2") + blog_post_2 = BlogPost(title="Blog Post #2") blog_post_2.published_date = datetime(2010, 1, 6, 0, 0 ,0) blog_post_3 = BlogPost(title="Blog Post #3") @@ -405,7 +419,7 @@ subsequent calls to :meth:`~mongoengine.queryset.QuerySet.order_by`. :: # get the "first" BlogPost using default ordering # from BlogPost.meta.ordering - latest_post = BlogPost.objects.first() + latest_post = BlogPost.objects.first() assert latest_post.title == "Blog Post #3" # override default ordering, order BlogPosts by "published_date" @@ -434,7 +448,7 @@ Working with existing data To enable correct retrieval of documents involved in this kind of heirarchy, two extra attributes are stored on each document in the database: :attr:`_cls` and :attr:`_types`. These are hidden from the user through the MongoEngine -interface, but may not be present if you are trying to use MongoEngine with +interface, but may not be present if you are trying to use MongoEngine with an existing database. For this reason, you may disable this inheritance mechansim, removing the dependency of :attr:`_cls` and :attr:`_types`, enabling you to work with existing databases. To disable inheritance on a document diff --git a/docs/guide/document-instances.rst b/docs/guide/document-instances.rst index aeed7cdb..317bfef1 100644 --- a/docs/guide/document-instances.rst +++ b/docs/guide/document-instances.rst @@ -4,12 +4,12 @@ Documents instances To create a new document object, create an instance of the relevant document class, providing values for its fields as its constructor keyword arguments. You may provide values for any of the fields on the document:: - + >>> page = Page(title="Test Page") >>> page.title 'Test Page' -You may also assign values to the document's fields using standard object +You may also assign values to the document's fields using standard object attribute syntax:: >>> page.title = "Example Page" @@ -18,9 +18,9 @@ attribute syntax:: Saving and deleting documents ============================= -MongoEngine tracks changes to documents to provide efficient saving. To save +MongoEngine tracks changes to documents to provide efficient saving. To save the document to the database, call the :meth:`~mongoengine.Document.save` method. -If the document does not exist in the database, it will be created. If it does +If the document does not exist in the database, it will be created. If it does already exist, then any changes will be updated atomically. For example:: >>> page = Page(title="Test Page") @@ -29,6 +29,7 @@ already exist, then any changes will be updated atomically. For example:: >>> page.save() # Performs an atomic set on the title field. .. note:: + Changes to documents are tracked and on the whole perform `set` operations. * ``list_field.pop(0)`` - *sets* the resulting list @@ -78,6 +79,7 @@ is an alias to :attr:`id`:: >>> page.id == page.pk .. note:: + If you define your own primary key field, the field implicitly becomes required, so a :class:`ValidationError` will be thrown if you don't provide it. diff --git a/docs/guide/gridfs.rst b/docs/guide/gridfs.rst index 0cd06539..3abad775 100644 --- a/docs/guide/gridfs.rst +++ b/docs/guide/gridfs.rst @@ -66,6 +66,7 @@ Deleting stored files is achieved with the :func:`delete` method:: marmot.photo.delete() .. note:: + The FileField in a Document actually only stores the ID of a file in a separate GridFS collection. This means that deleting a document with a defined FileField does not actually delete the file. You must be diff --git a/docs/guide/installing.rst b/docs/guide/installing.rst index 132f1079..f15d3dbb 100644 --- a/docs/guide/installing.rst +++ b/docs/guide/installing.rst @@ -1,31 +1,31 @@ ====================== Installing MongoEngine ====================== + To use MongoEngine, you will need to download `MongoDB `_ and ensure it is running in an accessible location. You will also need `PyMongo `_ to use MongoEngine, but if you install MongoEngine using setuptools, then the dependencies will be handled for you. -MongoEngine is available on PyPI, so to use it you can use -:program:`easy_install`: - +MongoEngine is available on PyPI, so to use it you can use :program:`pip`: + .. code-block:: console - # easy_install mongoengine + $ pip install mongoengine -Alternatively, if you don't have setuptools installed, `download it from PyPi +Alternatively, if you don't have setuptools installed, `download it from PyPi `_ and run .. code-block:: console - # python setup.py install + $ python setup.py install To use the bleeding-edge version of MongoEngine, you can get the source from `GitHub `_ and install it as above: - + .. code-block:: console - # git clone git://github.com/hmarr/mongoengine - # cd mongoengine - # python setup.py install + $ git clone git://github.com/hmarr/mongoengine + $ cd mongoengine + $ python setup.py install diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index c454b6e8..13e11106 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -14,6 +14,7 @@ fetch documents from the database:: print user.name .. note:: + Once the iteration finishes (when :class:`StopIteration` is raised), :meth:`~mongoengine.queryset.QuerySet.rewind` will be called so that the :class:`~mongoengine.queryset.QuerySet` may be iterated over again. The @@ -39,29 +40,6 @@ syntax:: # been written by a user whose 'country' field is set to 'uk' uk_pages = Page.objects(author__country='uk') -Querying lists --------------- -On most fields, this syntax will look up documents where the field specified -matches the given value exactly, but when the field refers to a -:class:`~mongoengine.ListField`, a single item may be provided, in which case -lists that contain that item will be matched:: - - class Page(Document): - tags = ListField(StringField()) - - # This will match all pages that have the word 'coding' as an item in the - # 'tags' list - Page.objects(tags='coding') - -Raw queries ------------ -It is possible to provide a raw PyMongo query as a query parameter, which will -be integrated directly into the query. This is done using the ``__raw__`` -keyword argument:: - - Page.objects(__raw__={'tags': 'coding'}) - -.. versionadded:: 0.4 Query operators =============== @@ -99,26 +77,67 @@ expressions: * ``endswith`` -- string field ends with value * ``iendswith`` -- string field ends with value (case insensitive) -.. versionadded:: 0.3 - There are a few special operators for performing geographical queries, that may used with :class:`~mongoengine.GeoPointField`\ s: * ``within_distance`` -- provide a list containing a point and a maximum distance (e.g. [(41.342, -87.653), 5]) +* ``within_spherical_distance`` -- Same as above but using the spherical geo model + (e.g. [(41.342, -87.653), 5/earth_radius]) +* ``near`` -- order the documents by how close they are to a given point +* ``near_sphere`` -- Same as above but using the spherical geo model * ``within_box`` -- filter documents to those within a given bounding box (e.g. [(35.0, -125.0), (40.0, -100.0)]) -* ``near`` -- order the documents by how close they are to a given point +* ``within_polygon`` -- filter documents to those within a given polygon (e.g. + [(41.91,-87.69), (41.92,-87.68), (41.91,-87.65), (41.89,-87.65)]). + .. note:: Requires Mongo Server 2.0 -.. versionadded:: 0.4 -Querying by position -==================== +Querying lists +-------------- +On most fields, this syntax will look up documents where the field specified +matches the given value exactly, but when the field refers to a +:class:`~mongoengine.ListField`, a single item may be provided, in which case +lists that contain that item will be matched:: + + class Page(Document): + tags = ListField(StringField()) + + # This will match all pages that have the word 'coding' as an item in the + # 'tags' list + Page.objects(tags='coding') + It is possible to query by position in a list by using a numerical value as a query operator. So if you wanted to find all pages whose first tag was ``db``, you could use the following query:: - BlogPost.objects(tags__0='db') + Page.objects(tags__0='db') + +If you only want to fetch part of a list eg: you want to paginate a list, then +the `slice` operator is required:: + + # comments - skip 5, limit 10 + Page.objects.fields(slice__comments=[5, 10]) + +For updating documents, if you don't know the position in a list, you can use +the $ positional operator :: + + Post.objects(comments__by="joe").update(**{'inc__comments__$__votes': 1}) + +However, this doesn't map well to the syntax so you can alos use a capital S instead :: + + Post.objects(comments__by="joe").update(inc__comments__S__votes=1) + + .. note:: Due to Mongo currently the $ operator only applies to the first matched item in the query. + + +Raw queries +----------- +It is possible to provide a raw PyMongo query as a query parameter, which will +be integrated directly into the query. This is done using the ``__raw__`` +keyword argument:: + + Page.objects(__raw__={'tags': 'coding'}) .. versionadded:: 0.4 @@ -270,6 +289,7 @@ You may sum over the values of a specific field on documents using yearly_expense = Employee.objects.sum('salary') .. note:: + If the field isn't present on a document, that document will be ignored from the sum. @@ -318,6 +338,11 @@ will be given:: >>> f.rating # default value 3 +.. note:: + + The :meth:`~mongoengine.queryset.QuerySet.exclude` is the opposite of + :meth:`~mongoengine.queryset.QuerySet.only` if you want to exclude a field. + If you later need the missing fields, just call :meth:`~mongoengine.Document.reload` on your document. @@ -341,6 +366,67 @@ calling it with keyword arguments:: # Get top posts Post.objects((Q(featured=True) & Q(hits__gte=1000)) | Q(hits__gte=5000)) +.. _guide-atomic-updates: + +Atomic updates +============== +Documents may be updated atomically by using the +:meth:`~mongoengine.queryset.QuerySet.update_one` and +:meth:`~mongoengine.queryset.QuerySet.update` methods on a +:meth:`~mongoengine.queryset.QuerySet`. There are several different "modifiers" +that you may use with these methods: + +* ``set`` -- set a particular value +* ``unset`` -- delete a particular value (since MongoDB v1.3+) +* ``inc`` -- increment a value by a given amount +* ``dec`` -- decrement a value by a given amount +* ``pop`` -- remove the last item from a list +* ``push`` -- append a value to a list +* ``push_all`` -- append several values to a list +* ``pop`` -- remove the first or last element of a list +* ``pull`` -- remove a value from a list +* ``pull_all`` -- remove several values from a list +* ``add_to_set`` -- add value to a list only if its not in the list already + +The syntax for atomic updates is similar to the querying syntax, but the +modifier comes before the field, not after it:: + + >>> post = BlogPost(title='Test', page_views=0, tags=['database']) + >>> post.save() + >>> BlogPost.objects(id=post.id).update_one(inc__page_views=1) + >>> post.reload() # the document has been changed, so we need to reload it + >>> post.page_views + 1 + >>> BlogPost.objects(id=post.id).update_one(set__title='Example Post') + >>> post.reload() + >>> post.title + 'Example Post' + >>> BlogPost.objects(id=post.id).update_one(push__tags='nosql') + >>> post.reload() + >>> post.tags + ['database', 'nosql'] + +.. note :: + + In version 0.5 the :meth:`~mongoengine.Document.save` runs atomic updates + on changed documents by tracking changes to that document. + +The positional operator allows you to update list items without knowing the +index position, therefore making the update a single atomic operation. As we +cannot use the `$` syntax in keyword arguments it has been mapped to `S`:: + + >>> post = BlogPost(title='Test', page_views=0, tags=['database', 'mongo']) + >>> post.save() + >>> BlogPost.objects(id=post.id, tags='mongo').update(set__tags__S='mongodb') + >>> post.reload() + >>> post.tags + ['database', 'mongodb'] + +.. note :: + Currently only top level lists are handled, future versions of mongodb / + pymongo plan to support nested positional operators. See `The $ positional + operator `_. + Server-side javascript execution ================================ Javascript functions may be written and sent to the server for execution. The @@ -443,59 +529,3 @@ following example shows how the substitutions are made:: return comments; } """) - -.. _guide-atomic-updates: - -Atomic updates -============== -Documents may be updated atomically by using the -:meth:`~mongoengine.queryset.QuerySet.update_one` and -:meth:`~mongoengine.queryset.QuerySet.update` methods on a -:meth:`~mongoengine.queryset.QuerySet`. There are several different "modifiers" -that you may use with these methods: - -* ``set`` -- set a particular value -* ``unset`` -- delete a particular value (since MongoDB v1.3+) -* ``inc`` -- increment a value by a given amount -* ``dec`` -- decrement a value by a given amount -* ``pop`` -- remove the last item from a list -* ``push`` -- append a value to a list -* ``push_all`` -- append several values to a list -* ``pop`` -- remove the first or last element of a list -* ``pull`` -- remove a value from a list -* ``pull_all`` -- remove several values from a list -* ``add_to_set`` -- add value to a list only if its not in the list already - -The syntax for atomic updates is similar to the querying syntax, but the -modifier comes before the field, not after it:: - - >>> post = BlogPost(title='Test', page_views=0, tags=['database']) - >>> post.save() - >>> BlogPost.objects(id=post.id).update_one(inc__page_views=1) - >>> post.reload() # the document has been changed, so we need to reload it - >>> post.page_views - 1 - >>> BlogPost.objects(id=post.id).update_one(set__title='Example Post') - >>> post.reload() - >>> post.title - 'Example Post' - >>> BlogPost.objects(id=post.id).update_one(push__tags='nosql') - >>> post.reload() - >>> post.tags - ['database', 'nosql'] - -The positional operator allows you to update list items without knowing the -index position, therefore making the update a single atomic operation. As we -cannot use the `$` syntax in keyword arguments it has been mapped to `S`:: - - >>> post = BlogPost(title='Test', page_views=0, tags=['database', 'mongo']) - >>> post.save() - >>> BlogPost.objects(id=post.id, tags='mongo').update(set__tags__S='mongodb') - >>> post.reload() - >>> post.tags - ['database', 'mongodb'] - -.. note :: - Currently only top level lists are handled, future versions of mongodb / - pymongo plan to support nested positional operators. See `The $ positional - operator `_. diff --git a/docs/guide/signals.rst b/docs/guide/signals.rst index 3c3159f8..58b3d6ed 100644 --- a/docs/guide/signals.rst +++ b/docs/guide/signals.rst @@ -41,9 +41,9 @@ Example usage:: logging.debug("Created") else: logging.debug("Updated") - + signals.pre_save.connect(Author.pre_save, sender=Author) signals.post_save.connect(Author.post_save, sender=Author) -.. _blinker: http://pypi.python.org/pypi/blinker \ No newline at end of file +.. _blinker: http://pypi.python.org/pypi/blinker diff --git a/docs/index.rst b/docs/index.rst index 3b036564..920ddf60 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,35 +2,62 @@ MongoEngine User Documentation ============================== -MongoEngine is an Object-Document Mapper, written in Python for working with +**MongoEngine** is an Object-Document Mapper, written in Python for working with MongoDB. To install it, simply run .. code-block:: console # pip install -U mongoengine -The source is available on `GitHub `_. +:doc:`tutorial` + Start here for a quick overview. + +:doc:`guide/index` + The Full guide to MongoEngine + +:doc:`apireference` + The complete API documentation. + +:doc:`django` + Using MongoEngine and Django + +Community +--------- To get help with using MongoEngine, use the `MongoEngine Users mailing list `_ or come chat on the `#mongoengine IRC channel `_. -If you are interested in contributing, join the developers' `mailing list +Contributing +------------ + +The source is available on `GitHub `_ and +contributions are always encouraged. Contributions can be as simple as +minor tweaks to this documentation. To contribute, fork the project on +`GitHub `_ and send a +pull request. + +Also, you can join the developers' `mailing list `_. +Changes +------- +See the :doc:`changelog` for a full list of changes to MongoEngine. + .. toctree:: - :maxdepth: 2 + :hidden: tutorial guide/index apireference django changelog - upgrading + upgrade Indices and tables -================== +------------------ * :ref:`genindex` +* :ref:`modindex` * :ref:`search` diff --git a/docs/upgrade.rst b/docs/upgrade.rst index 7187adcf..c684c1ad 100644 --- a/docs/upgrade.rst +++ b/docs/upgrade.rst @@ -5,24 +5,33 @@ Upgrading 0.4 to 0.5 =========== -There have been the following backwards incompatibilities from 0.4 to 0.5: +There have been the following backwards incompatibilities from 0.4 to 0.5. The +main areas of changed are: choices in fields, map_reduce and collection names. -# Choice options: +Choice options: +-------------- Are now expected to be an iterable of tuples, with the first element in each tuple being the actual value to be stored. The second element is the human-readable name for the option. -# PyMongo / MongoDB -map reduce now requires pymongo 1.11+ More methods now use map_reduce as db.eval -is not supported for sharding - the following have been changed: +PyMongo / MongoDB +----------------- - * sum - * average - * item_frequencies +map reduce now requires pymongo 1.11+- The pymongo merge_output and reduce_output +parameters, have been depreciated. -#. Default collection naming. +More methods now use map_reduce as db.eval is not supported for sharding as such +the following have been changed: + + * :meth:`~mongoengine.queryset.QuerySet.sum` + * :meth:`~mongoengine.queryset.QuerySet.average` + * :meth:`~mongoengine.queryset.QuerySet.item_frequencies` + + +Default collection naming +------------------------- Previously it was just lowercase, its now much more pythonic and readable as its lowercase and underscores, previously :: diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index a830150a..a6626855 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -744,7 +744,7 @@ class QuerySet(object): :param write_options: optional extra keyword arguments used if we have to create a new document. - Passes any write_options onto :meth:`~mongoengine.document.Document.save` + Passes any write_options onto :meth:`~mongoengine.Document.save` .. versionadded:: 0.3 """ @@ -901,9 +901,11 @@ class QuerySet(object): Returns an iterator yielding :class:`~mongoengine.document.MapReduceDocument`. - .. note:: Map/Reduce changed in server version **>= 1.7.4**. The PyMongo - :meth:`~pymongo.collection.Collection.map_reduce` helper requires - PyMongo version **>= 1.11**. + .. note:: + + Map/Reduce changed in server version **>= 1.7.4**. The PyMongo + :meth:`~pymongo.collection.Collection.map_reduce` helper requires + PyMongo version **>= 1.11**. .. versionchanged:: 0.5 - removed ``keep_temp`` keyword argument, which was only relevant @@ -1070,8 +1072,7 @@ class QuerySet(object): and `.exclude()` to manipulate which fields to retrieve. Fields also allows for a greater level of control for example: - Retrieving a Subrange of Array Elements - --------------------------------------- + Retrieving a Subrange of Array Elements: You can use the $slice operator to retrieve a subrange of elements in an array :: @@ -1500,6 +1501,7 @@ class QuerySet(object): This is useful for generating tag clouds, or searching documents. .. note:: + Can only do direct simple mappings and cannot map across :class:`~mongoengine.ReferenceField` or :class:`~mongoengine.GenericReferenceField` for more complex