00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 """Collection level utilities for Mongo."""
00016
00017 import warnings
00018
00019 from bson.code import Code
00020 from bson.son import SON
00021 from pymongo import (helpers,
00022 message)
00023 from pymongo.cursor import Cursor
00024 from pymongo.errors import InvalidName, InvalidOperation
00025
00026 _ZERO = "\x00\x00\x00\x00"
00027
00028
00029 def _gen_index_name(keys):
00030 """Generate an index name from the set of fields it is over.
00031 """
00032 return u"_".join([u"%s_%s" % item for item in keys])
00033
00034
00035 class Collection(object):
00036 """A Mongo collection.
00037 """
00038
00039 def __init__(self, database, name, options=None, create=False, **kwargs):
00040 """Get / create a Mongo collection.
00041
00042 Raises :class:`TypeError` if `name` is not an instance of
00043 :class:`basestring`. Raises
00044 :class:`~pymongo.errors.InvalidName` if `name` is not a valid
00045 collection name. Any additional keyword arguments will be used
00046 as options passed to the create command. See
00047 :meth:`~pymongo.database.Database.create_collection` for valid
00048 options.
00049
00050 If `create` is ``True`` or additional keyword arguments are
00051 present a create command will be sent. Otherwise, a create
00052 command will not be sent and the collection will be created
00053 implicitly on first use.
00054
00055 :Parameters:
00056 - `database`: the database to get a collection from
00057 - `name`: the name of the collection to get
00058 - `options`: DEPRECATED dictionary of collection options
00059 - `create` (optional): if ``True``, force collection
00060 creation even without options being set
00061 - `**kwargs` (optional): additional keyword arguments will
00062 be passed as options for the create collection command
00063
00064 .. versionchanged:: 1.5
00065 deprecating `options` in favor of kwargs
00066 .. versionadded:: 1.5
00067 the `create` parameter
00068
00069 .. mongodoc:: collections
00070 """
00071 if not isinstance(name, basestring):
00072 raise TypeError("name must be an instance of basestring")
00073
00074 if options is not None:
00075 warnings.warn("the options argument to Collection is deprecated "
00076 "and will be removed. please use kwargs instead.",
00077 DeprecationWarning)
00078 if not isinstance(options, dict):
00079 raise TypeError("options must be an instance of dict")
00080 options.update(kwargs)
00081 elif kwargs:
00082 options = kwargs
00083
00084 if not name or ".." in name:
00085 raise InvalidName("collection names cannot be empty")
00086 if "$" in name and not (name.startswith("oplog.$main") or
00087 name.startswith("$cmd")):
00088 raise InvalidName("collection names must not "
00089 "contain '$': %r" % name)
00090 if name[0] == "." or name[-1] == ".":
00091 raise InvalidName("collection names must not start "
00092 "or end with '.': %r" % name)
00093 if "\x00" in name:
00094 raise InvalidName("collection names must not contain the "
00095 "null character")
00096
00097 self.__database = database
00098 self.__name = unicode(name)
00099 self.__full_name = u"%s.%s" % (self.__database.name, self.__name)
00100 if create or options is not None:
00101 self.__create(options)
00102
00103 def __create(self, options):
00104 """Sends a create command with the given options.
00105 """
00106
00107
00108
00109 if options:
00110 if "size" in options:
00111 options["size"] = float(options["size"])
00112 self.__database.command("create", self.__name, **options)
00113 else:
00114 self.__database.command("create", self.__name)
00115
00116 def __getattr__(self, name):
00117 """Get a sub-collection of this collection by name.
00118
00119 Raises InvalidName if an invalid collection name is used.
00120
00121 :Parameters:
00122 - `name`: the name of the collection to get
00123 """
00124 return Collection(self.__database, u"%s.%s" % (self.__name, name))
00125
00126 def __getitem__(self, name):
00127 return self.__getattr__(name)
00128
00129 def __repr__(self):
00130 return "Collection(%r, %r)" % (self.__database, self.__name)
00131
00132 def __cmp__(self, other):
00133 if isinstance(other, Collection):
00134 return cmp((self.__database, self.__name),
00135 (other.__database, other.__name))
00136 return NotImplemented
00137
00138 @property
00139 def full_name(self):
00140 """The full name of this :class:`Collection`.
00141
00142 The full name is of the form `database_name.collection_name`.
00143
00144 .. versionchanged:: 1.3
00145 ``full_name`` is now a property rather than a method.
00146 """
00147 return self.__full_name
00148
00149 @property
00150 def name(self):
00151 """The name of this :class:`Collection`.
00152
00153 .. versionchanged:: 1.3
00154 ``name`` is now a property rather than a method.
00155 """
00156 return self.__name
00157
00158 @property
00159 def database(self):
00160 """The :class:`~pymongo.database.Database` that this
00161 :class:`Collection` is a part of.
00162
00163 .. versionchanged:: 1.3
00164 ``database`` is now a property rather than a method.
00165 """
00166 return self.__database
00167
00168 def save(self, to_save, manipulate=True, safe=False, **kwargs):
00169 """Save a document in this collection.
00170
00171 If `to_save` already has an ``"_id"`` then an :meth:`update`
00172 (upsert) operation is performed and any existing document with
00173 that ``"_id"`` is overwritten. Otherwise an ``"_id"`` will be
00174 added to `to_save` and an :meth:`insert` operation is
00175 performed. Returns the ``"_id"`` of the saved document.
00176
00177 Raises :class:`TypeError` if `to_save` is not an instance of
00178 :class:`dict`. If `safe` is ``True`` then the save will be
00179 checked for errors, raising
00180 :class:`~pymongo.errors.OperationFailure` if one
00181 occurred. Safe inserts wait for a response from the database,
00182 while normal inserts do not.
00183
00184 Any additional keyword arguments imply ``safe=True``, and will
00185 be used as options for the resultant `getLastError`
00186 command. For example, to wait for replication to 3 nodes, pass
00187 ``w=3``.
00188
00189 :Parameters:
00190 - `to_save`: the document to be saved
00191 - `manipulate` (optional): manipulate the document before
00192 saving it?
00193 - `safe` (optional): check that the save succeeded?
00194 - `**kwargs` (optional): any additional arguments imply
00195 ``safe=True``, and will be used as options for the
00196 `getLastError` command
00197
00198 .. versionadded:: 1.8
00199 Support for passing `getLastError` options as keyword
00200 arguments.
00201
00202 .. mongodoc:: insert
00203 """
00204 if not isinstance(to_save, dict):
00205 raise TypeError("cannot save object of type %s" % type(to_save))
00206
00207 if "_id" not in to_save:
00208 return self.insert(to_save, manipulate, safe, **kwargs)
00209 else:
00210 self.update({"_id": to_save["_id"]}, to_save, True,
00211 manipulate, safe, **kwargs)
00212 return to_save.get("_id", None)
00213
00214 def insert(self, doc_or_docs,
00215 manipulate=True, safe=False, check_keys=True, **kwargs):
00216 """Insert a document(s) into this collection.
00217
00218 If `manipulate` is set, the document(s) are manipulated using
00219 any :class:`~pymongo.son_manipulator.SONManipulator` instances
00220 that have been added to this
00221 :class:`~pymongo.database.Database`. Returns the ``"_id"`` of
00222 the inserted document or a list of ``"_id"`` values of the
00223 inserted documents. If the document(s) does not already
00224 contain an ``"_id"`` one will be added.
00225
00226 If `safe` is ``True`` then the insert will be checked for
00227 errors, raising :class:`~pymongo.errors.OperationFailure` if
00228 one occurred. Safe inserts wait for a response from the
00229 database, while normal inserts do not.
00230
00231 Any additional keyword arguments imply ``safe=True``, and
00232 will be used as options for the resultant `getLastError`
00233 command. For example, to wait for replication to 3 nodes, pass
00234 ``w=3``.
00235
00236 :Parameters:
00237 - `doc_or_docs`: a document or list of documents to be
00238 inserted
00239 - `manipulate` (optional): manipulate the documents before
00240 inserting?
00241 - `safe` (optional): check that the insert succeeded?
00242 - `check_keys` (optional): check if keys start with '$' or
00243 contain '.', raising :class:`~pymongo.errors.InvalidName`
00244 in either case
00245 - `**kwargs` (optional): any additional arguments imply
00246 ``safe=True``, and will be used as options for the
00247 `getLastError` command
00248
00249 .. versionadded:: 1.8
00250 Support for passing `getLastError` options as keyword
00251 arguments.
00252 .. versionchanged:: 1.1
00253 Bulk insert works with any iterable
00254
00255 .. mongodoc:: insert
00256 """
00257 docs = doc_or_docs
00258 return_one = False
00259 if isinstance(docs, dict):
00260 return_one = True
00261 docs = [docs]
00262
00263 if manipulate:
00264 docs = [self.__database._fix_incoming(doc, self) for doc in docs]
00265
00266 if kwargs:
00267 safe = True
00268 self.__database.connection._send_message(
00269 message.insert(self.__full_name, docs,
00270 check_keys, safe, kwargs), safe)
00271
00272 ids = [doc.get("_id", None) for doc in docs]
00273 return return_one and ids[0] or ids
00274
00275 def update(self, spec, document, upsert=False, manipulate=False,
00276 safe=False, multi=False, **kwargs):
00277 """Update a document(s) in this collection.
00278
00279 Raises :class:`TypeError` if either `spec` or `document` is
00280 not an instance of ``dict`` or `upsert` is not an instance of
00281 ``bool``. If `safe` is ``True`` then the update will be
00282 checked for errors, raising
00283 :class:`~pymongo.errors.OperationFailure` if one
00284 occurred. Safe updates require a response from the database,
00285 while normal updates do not - thus, setting `safe` to ``True``
00286 will negatively impact performance.
00287
00288 There are many useful `update modifiers`_ which can be used
00289 when performing updates. For example, here we use the
00290 ``"$set"`` modifier to modify some fields in a matching
00291 document:
00292
00293 .. doctest::
00294
00295 >>> db.test.insert({"x": "y", "a": "b"})
00296 ObjectId('...')
00297 >>> list(db.test.find())
00298 [{u'a': u'b', u'x': u'y', u'_id': ObjectId('...')}]
00299 >>> db.test.update({"x": "y"}, {"$set": {"a": "c"}})
00300 >>> list(db.test.find())
00301 [{u'a': u'c', u'x': u'y', u'_id': ObjectId('...')}]
00302
00303 If `safe` is ``True`` returns the response to the *lastError*
00304 command. Otherwise, returns ``None``.
00305
00306 Any additional keyword arguments imply ``safe=True``, and will
00307 be used as options for the resultant `getLastError`
00308 command. For example, to wait for replication to 3 nodes, pass
00309 ``w=3``.
00310
00311 :Parameters:
00312 - `spec`: a ``dict`` or :class:`~bson.son.SON` instance
00313 specifying elements which must be present for a document
00314 to be updated
00315 - `document`: a ``dict`` or :class:`~bson.son.SON`
00316 instance specifying the document to be used for the update
00317 or (in the case of an upsert) insert - see docs on MongoDB
00318 `update modifiers`_
00319 - `upsert` (optional): perform an upsert if ``True``
00320 - `manipulate` (optional): manipulate the document before
00321 updating? If ``True`` all instances of
00322 :mod:`~pymongo.son_manipulator.SONManipulator` added to
00323 this :class:`~pymongo.database.Database` will be applied
00324 to the document before performing the update.
00325 - `safe` (optional): check that the update succeeded?
00326 - `multi` (optional): update all documents that match
00327 `spec`, rather than just the first matching document. The
00328 default value for `multi` is currently ``False``, but this
00329 might eventually change to ``True``. It is recommended
00330 that you specify this argument explicitly for all update
00331 operations in order to prepare your code for that change.
00332 - `**kwargs` (optional): any additional arguments imply
00333 ``safe=True``, and will be used as options for the
00334 `getLastError` command
00335
00336 .. versionadded:: 1.8
00337 Support for passing `getLastError` options as keyword
00338 arguments.
00339 .. versionchanged:: 1.4
00340 Return the response to *lastError* if `safe` is ``True``.
00341 .. versionadded:: 1.1.1
00342 The `multi` parameter.
00343
00344 .. _update modifiers: http://www.mongodb.org/display/DOCS/Updating
00345
00346 .. mongodoc:: update
00347 """
00348 if not isinstance(spec, dict):
00349 raise TypeError("spec must be an instance of dict")
00350 if not isinstance(document, dict):
00351 raise TypeError("document must be an instance of dict")
00352 if not isinstance(upsert, bool):
00353 raise TypeError("upsert must be an instance of bool")
00354
00355 if upsert and manipulate:
00356 document = self.__database._fix_incoming(document, self)
00357
00358 if kwargs:
00359 safe = True
00360
00361 return self.__database.connection._send_message(
00362 message.update(self.__full_name, upsert, multi,
00363 spec, document, safe, kwargs), safe)
00364
00365 def drop(self):
00366 """Alias for :meth:`~pymongo.database.Database.drop_collection`.
00367
00368 The following two calls are equivalent:
00369
00370 >>> db.foo.drop()
00371 >>> db.drop_collection("foo")
00372
00373 .. versionadded:: 1.8
00374 """
00375 self.__database.drop_collection(self.__name)
00376
00377 def remove(self, spec_or_id=None, safe=False, **kwargs):
00378 """Remove a document(s) from this collection.
00379
00380 .. warning:: Calls to :meth:`remove` should be performed with
00381 care, as removed data cannot be restored.
00382
00383 If `safe` is ``True`` then the remove operation will be
00384 checked for errors, raising
00385 :class:`~pymongo.errors.OperationFailure` if one
00386 occurred. Safe removes wait for a response from the database,
00387 while normal removes do not.
00388
00389 If `spec_or_id` is ``None``, all documents in this collection
00390 will be removed. This is not equivalent to calling
00391 :meth:`~pymongo.database.Database.drop_collection`, however,
00392 as indexes will not be removed.
00393
00394 If `safe` is ``True`` returns the response to the *lastError*
00395 command. Otherwise, returns ``None``.
00396
00397 Any additional keyword arguments imply ``safe=True``, and will
00398 be used as options for the resultant `getLastError`
00399 command. For example, to wait for replication to 3 nodes, pass
00400 ``w=3``.
00401
00402 :Parameters:
00403 - `spec_or_id` (optional): a dictionary specifying the
00404 documents to be removed OR any other type specifying the
00405 value of ``"_id"`` for the document to be removed
00406 - `safe` (optional): check that the remove succeeded?
00407 - `**kwargs` (optional): any additional arguments imply
00408 ``safe=True``, and will be used as options for the
00409 `getLastError` command
00410
00411 .. versionadded:: 1.8
00412 Support for passing `getLastError` options as keyword arguments.
00413 .. versionchanged:: 1.7 Accept any type other than a ``dict``
00414 instance for removal by ``"_id"``, not just
00415 :class:`~bson.objectid.ObjectId` instances.
00416 .. versionchanged:: 1.4
00417 Return the response to *lastError* if `safe` is ``True``.
00418 .. versionchanged:: 1.2
00419 The `spec_or_id` parameter is now optional. If it is
00420 not specified *all* documents in the collection will be
00421 removed.
00422 .. versionadded:: 1.1
00423 The `safe` parameter.
00424
00425 .. mongodoc:: remove
00426 """
00427 if spec_or_id is None:
00428 spec_or_id = {}
00429 if not isinstance(spec_or_id, dict):
00430 spec_or_id = {"_id": spec_or_id}
00431
00432 if kwargs:
00433 safe = True
00434
00435 return self.__database.connection._send_message(
00436 message.delete(self.__full_name, spec_or_id, safe, kwargs), safe)
00437
00438 def find_one(self, spec_or_id=None, *args, **kwargs):
00439 """Get a single document from the database.
00440
00441 All arguments to :meth:`find` are also valid arguments for
00442 :meth:`find_one`, although any `limit` argument will be
00443 ignored. Returns a single document, or ``None`` if no matching
00444 document is found.
00445
00446 :Parameters:
00447
00448 - `spec_or_id` (optional): a dictionary specifying
00449 the query to be performed OR any other type to be used as
00450 the value for a query for ``"_id"``.
00451
00452 - `*args` (optional): any additional positional arguments
00453 are the same as the arguments to :meth:`find`.
00454
00455 - `**kwargs` (optional): any additional keyword arguments
00456 are the same as the arguments to :meth:`find`.
00457
00458 .. versionchanged:: 1.7
00459 Allow passing any of the arguments that are valid for
00460 :meth:`find`.
00461
00462 .. versionchanged:: 1.7 Accept any type other than a ``dict``
00463 instance as an ``"_id"`` query, not just
00464 :class:`~bson.objectid.ObjectId` instances.
00465 """
00466 if spec_or_id is not None and not isinstance(spec_or_id, dict):
00467 spec_or_id = {"_id": spec_or_id}
00468
00469 for result in self.find(spec_or_id, *args, **kwargs).limit(-1):
00470 return result
00471 return None
00472
00473 def find(self, *args, **kwargs):
00474 """Query the database.
00475
00476 The `spec` argument is a prototype document that all results
00477 must match. For example:
00478
00479 >>> db.test.find({"hello": "world"})
00480
00481 only matches documents that have a key "hello" with value
00482 "world". Matches can have other keys *in addition* to
00483 "hello". The `fields` argument is used to specify a subset of
00484 fields that should be included in the result documents. By
00485 limiting results to a certain subset of fields you can cut
00486 down on network traffic and decoding time.
00487
00488 Raises :class:`TypeError` if any of the arguments are of
00489 improper type. Returns an instance of
00490 :class:`~pymongo.cursor.Cursor` corresponding to this query.
00491
00492 :Parameters:
00493 - `spec` (optional): a SON object specifying elements which
00494 must be present for a document to be included in the
00495 result set
00496 - `fields` (optional): a list of field names that should be
00497 returned in the result set ("_id" will always be
00498 included), or a dict specifying the fields to return
00499 - `skip` (optional): the number of documents to omit (from
00500 the start of the result set) when returning the results
00501 - `limit` (optional): the maximum number of results to
00502 return
00503 - `timeout` (optional): if True, any returned cursor will be
00504 subject to the normal timeout behavior of the mongod
00505 process. Otherwise, the returned cursor will never timeout
00506 at the server. Care should be taken to ensure that cursors
00507 with timeout turned off are properly closed.
00508 - `snapshot` (optional): if True, snapshot mode will be used
00509 for this query. Snapshot mode assures no duplicates are
00510 returned, or objects missed, which were present at both
00511 the start and end of the query's execution. For details,
00512 see the `snapshot documentation
00513 <http://dochub.mongodb.org/core/snapshot>`_.
00514 - `tailable` (optional): the result of this find call will
00515 be a tailable cursor - tailable cursors aren't closed when
00516 the last data is retrieved but are kept open and the
00517 cursors location marks the final document's position. if
00518 more data is received iteration of the cursor will
00519 continue from the last document received. For details, see
00520 the `tailable cursor documentation
00521 <http://www.mongodb.org/display/DOCS/Tailable+Cursors>`_.
00522 - `sort` (optional): a list of (key, direction) pairs
00523 specifying the sort order for this query. See
00524 :meth:`~pymongo.cursor.Cursor.sort` for details.
00525 - `max_scan` (optional): limit the number of documents
00526 examined when performing the query
00527 - `as_class` (optional): class to use for documents in the
00528 query result (default is
00529 :attr:`~pymongo.connection.Connection.document_class`)
00530 - `network_timeout` (optional): specify a timeout to use for
00531 this query, which will override the
00532 :class:`~pymongo.connection.Connection`-level default
00533
00534 .. note:: The `max_scan` parameter requires server
00535 version **>= 1.5.1**
00536
00537 .. versionadded:: 1.8
00538 The `network_timeout` parameter.
00539
00540 .. versionadded:: 1.7
00541 The `sort`, `max_scan` and `as_class` parameters.
00542
00543 .. versionchanged:: 1.7
00544 The `fields` parameter can now be a dict or any iterable in
00545 addition to a list.
00546
00547 .. versionadded:: 1.1
00548 The `tailable` parameter.
00549
00550 .. mongodoc:: find
00551 """
00552 return Cursor(self, *args, **kwargs)
00553
00554 def count(self):
00555 """Get the number of documents in this collection.
00556
00557 To get the number of documents matching a specific query use
00558 :meth:`pymongo.cursor.Cursor.count`.
00559 """
00560 return self.find().count()
00561
00562 def create_index(self, key_or_list, deprecated_unique=None,
00563 ttl=300, **kwargs):
00564 """Creates an index on this collection.
00565
00566 Takes either a single key or a list of (key, direction) pairs.
00567 The key(s) must be an instance of :class:`basestring`, and the
00568 directions must be one of (:data:`~pymongo.ASCENDING`,
00569 :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). Returns
00570 the name of the created index.
00571
00572 To create a single key index on the key ``'mike'`` we just use
00573 a string argument:
00574
00575 >>> my_collection.create_index("mike")
00576
00577 For a compound index on ``'mike'`` descending and ``'eliot'``
00578 ascending we need to use a list of tuples:
00579
00580 >>> my_collection.create_index([("mike", pymongo.DESCENDING),
00581 ... ("eliot", pymongo.ASCENDING)])
00582
00583 All optional index creation paramaters should be passed as
00584 keyword arguments to this method. Valid options include:
00585
00586 - `name`: custom name to use for this index - if none is
00587 given, a name will be generated
00588 - `unique`: should this index guarantee uniqueness?
00589 - `dropDups` or `drop_dups`: should we drop duplicates
00590 during index creation when creating a unique index?
00591 - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
00592 index
00593 - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
00594 index
00595
00596 :Parameters:
00597 - `key_or_list`: a single key or a list of (key, direction)
00598 pairs specifying the index to create
00599 - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
00600 - `ttl` (optional): time window (in seconds) during which
00601 this index will be recognized by subsequent calls to
00602 :meth:`ensure_index` - see documentation for
00603 :meth:`ensure_index` for details
00604 - `**kwargs` (optional): any additional index creation
00605 options (see the above list) should be passed as keyword
00606 arguments
00607
00608 .. versionchanged:: 1.5.1
00609 Accept kwargs to support all index creation options.
00610
00611 .. versionadded:: 1.5
00612 The `name` parameter.
00613
00614 .. seealso:: :meth:`ensure_index`
00615
00616 .. mongodoc:: indexes
00617 """
00618 keys = helpers._index_list(key_or_list)
00619 index_doc = helpers._index_document(keys)
00620
00621 index = {"key": index_doc, "ns": self.__full_name}
00622
00623 if deprecated_unique is not None:
00624 warnings.warn("using a positional arg to specify unique is "
00625 "deprecated, please use kwargs",
00626 DeprecationWarning)
00627 index["unique"] = deprecated_unique
00628
00629 name = "name" in kwargs and kwargs["name"] or _gen_index_name(keys)
00630 index["name"] = name
00631
00632 if "drop_dups" in kwargs:
00633 kwargs["dropDups"] = kwargs.pop("drop_dups")
00634
00635 index.update(kwargs)
00636
00637 self.__database.system.indexes.insert(index, manipulate=False,
00638 check_keys=False,
00639 safe=True)
00640
00641 self.__database.connection._cache_index(self.__database.name,
00642 self.__name, name, ttl)
00643
00644 return name
00645
00646 def ensure_index(self, key_or_list, deprecated_unique=None,
00647 ttl=300, **kwargs):
00648 """Ensures that an index exists on this collection.
00649
00650 Takes either a single key or a list of (key, direction) pairs.
00651 The key(s) must be an instance of :class:`basestring`, and the
00652 direction(s) must be one of (:data:`~pymongo.ASCENDING`,
00653 :data:`~pymongo.DESCENDING`, :data:`~pymongo.GEO2D`). See
00654 :meth:`create_index` for a detailed example.
00655
00656 Unlike :meth:`create_index`, which attempts to create an index
00657 unconditionally, :meth:`ensure_index` takes advantage of some
00658 caching within the driver such that it only attempts to create
00659 indexes that might not already exist. When an index is created
00660 (or ensured) by PyMongo it is "remembered" for `ttl`
00661 seconds. Repeated calls to :meth:`ensure_index` within that
00662 time limit will be lightweight - they will not attempt to
00663 actually create the index.
00664
00665 Care must be taken when the database is being accessed through
00666 multiple connections at once. If an index is created using
00667 PyMongo and then deleted using another connection any call to
00668 :meth:`ensure_index` within the cache window will fail to
00669 re-create the missing index.
00670
00671 Returns the name of the created index if an index is actually
00672 created. Returns ``None`` if the index already exists.
00673
00674 All optional index creation paramaters should be passed as
00675 keyword arguments to this method. Valid options include:
00676
00677 - `name`: custom name to use for this index - if none is
00678 given, a name will be generated
00679 - `unique`: should this index guarantee uniqueness?
00680 - `dropDups` or `drop_dups`: should we drop duplicates
00681 during index creation when creating a unique index?
00682 - `background`: if this index should be created in the
00683 background
00684 - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
00685 index
00686 - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
00687 index
00688
00689 :Parameters:
00690 - `key_or_list`: a single key or a list of (key, direction)
00691 pairs specifying the index to create
00692 - `deprecated_unique`: DEPRECATED - use `unique` as a kwarg
00693 - `ttl` (optional): time window (in seconds) during which
00694 this index will be recognized by subsequent calls to
00695 :meth:`ensure_index`
00696 - `**kwargs` (optional): any additional index creation
00697 options (see the above list) should be passed as keyword
00698 arguments
00699
00700 .. versionchanged:: 1.5.1
00701 Accept kwargs to support all index creation options.
00702
00703 .. versionadded:: 1.5
00704 The `name` parameter.
00705
00706 .. seealso:: :meth:`create_index`
00707 """
00708 if "name" in kwargs:
00709 name = kwargs["name"]
00710 else:
00711 keys = helpers._index_list(key_or_list)
00712 name = kwargs["name"] = _gen_index_name(keys)
00713
00714 if self.__database.connection._cache_index(self.__database.name,
00715 self.__name, name, ttl):
00716 return self.create_index(key_or_list, deprecated_unique,
00717 ttl, **kwargs)
00718 return None
00719
00720 def drop_indexes(self):
00721 """Drops all indexes on this collection.
00722
00723 Can be used on non-existant collections or collections with no indexes.
00724 Raises OperationFailure on an error.
00725 """
00726 self.__database.connection._purge_index(self.__database.name,
00727 self.__name)
00728 self.drop_index(u"*")
00729
00730 def drop_index(self, index_or_name):
00731 """Drops the specified index on this collection.
00732
00733 Can be used on non-existant collections or collections with no
00734 indexes. Raises OperationFailure on an error. `index_or_name`
00735 can be either an index name (as returned by `create_index`),
00736 or an index specifier (as passed to `create_index`). An index
00737 specifier should be a list of (key, direction) pairs. Raises
00738 TypeError if index is not an instance of (str, unicode, list).
00739
00740 .. warning:: if a custom name was used on index creation (by
00741 passing the `name` parameter to :meth:`create_index` or
00742 :meth:`ensure_index`) the index **must** be dropped by name.
00743
00744 :Parameters:
00745 - `index_or_name`: index (or name of index) to drop
00746 """
00747 name = index_or_name
00748 if isinstance(index_or_name, list):
00749 name = _gen_index_name(index_or_name)
00750
00751 if not isinstance(name, basestring):
00752 raise TypeError("index_or_name must be an index name or list")
00753
00754 self.__database.connection._purge_index(self.__database.name,
00755 self.__name, name)
00756 self.__database.command("dropIndexes", self.__name, index=name,
00757 allowable_errors=["ns not found"])
00758
00759 def index_information(self):
00760 """Get information on this collection's indexes.
00761
00762 Returns a dictionary where the keys are index names (as
00763 returned by create_index()) and the values are dictionaries
00764 containing information about each index. The dictionary is
00765 guaranteed to contain at least a single key, ``"key"`` which
00766 is a list of (key, direction) pairs specifying the index (as
00767 passed to create_index()). It will also contain any other
00768 information in `system.indexes`, except for the ``"ns"`` and
00769 ``"name"`` keys, which are cleaned. Example output might look
00770 like this:
00771
00772 >>> db.test.ensure_index("x", unique=True)
00773 u'x_1'
00774 >>> db.test.index_information()
00775 {u'_id_': {u'key': [(u'_id', 1)]},
00776 u'x_1': {u'unique': True, u'key': [(u'x', 1)]}}
00777
00778
00779 .. versionchanged:: 1.7
00780 The values in the resultant dictionary are now dictionaries
00781 themselves, whose ``"key"`` item contains the list that was
00782 the value in previous versions of PyMongo.
00783 """
00784 raw = self.__database.system.indexes.find({"ns": self.__full_name},
00785 {"ns": 0}, as_class=SON)
00786 info = {}
00787 for index in raw:
00788 index["key"] = index["key"].items()
00789 index = dict(index)
00790 info[index.pop("name")] = index
00791 return info
00792
00793 def options(self):
00794 """Get the options set on this collection.
00795
00796 Returns a dictionary of options and their values - see
00797 :meth:`~pymongo.database.Database.create_collection` for more
00798 information on the possible options. Returns an empty
00799 dictionary if the collection has not been created yet.
00800 """
00801 result = self.__database.system.namespaces.find_one(
00802 {"name": self.__full_name})
00803
00804 if not result:
00805 return {}
00806
00807 options = result.get("options", {})
00808 if "create" in options:
00809 del options["create"]
00810
00811 return options
00812
00813
00814
00815 def group(self, key, condition, initial, reduce, finalize=None,
00816 command=True):
00817 """Perform a query similar to an SQL *group by* operation.
00818
00819 Returns an array of grouped items.
00820
00821 The `key` parameter can be:
00822
00823 - ``None`` to use the entire document as a key.
00824 - A :class:`list` of keys (each a :class:`basestring`) to group by.
00825 - A :class:`basestring` or :class:`~bson.code.Code` instance
00826 containing a JavaScript function to be applied to each
00827 document, returning the key to group by.
00828
00829 :Parameters:
00830 - `key`: fields to group by (see above description)
00831 - `condition`: specification of rows to be
00832 considered (as a :meth:`find` query specification)
00833 - `initial`: initial value of the aggregation counter object
00834 - `reduce`: aggregation function as a JavaScript string
00835 - `finalize`: function to be called on each object in output list.
00836 - `command` (optional): DEPRECATED if ``True``, run the group as a
00837 command instead of in an eval - this option is deprecated and
00838 will be removed in favor of running all groups as commands
00839
00840 .. versionchanged:: 1.4
00841 The `key` argument can now be ``None`` or a JavaScript function,
00842 in addition to a :class:`list` of keys.
00843 .. versionchanged:: 1.3
00844 The `command` argument now defaults to ``True`` and is deprecated.
00845 """
00846 if not command:
00847 warnings.warn("eval-based groups are deprecated, and the "
00848 "command option will be removed.",
00849 DeprecationWarning)
00850
00851 group = {}
00852 if isinstance(key, basestring):
00853 group["$keyf"] = Code(key)
00854 elif key is not None:
00855 group = {"key": helpers._fields_list_to_dict(key)}
00856 group["ns"] = self.__name
00857 group["$reduce"] = Code(reduce)
00858 group["cond"] = condition
00859 group["initial"] = initial
00860 if finalize is not None:
00861 group["finalize"] = Code(finalize)
00862
00863 return self.__database.command("group", group)["retval"]
00864
00865 def rename(self, new_name, **kwargs):
00866 """Rename this collection.
00867
00868 If operating in auth mode, client must be authorized as an
00869 admin to perform this operation. Raises :class:`TypeError` if
00870 `new_name` is not an instance of :class:`basestring`. Raises
00871 :class:`~pymongo.errors.InvalidName` if `new_name` is not a
00872 valid collection name.
00873
00874 :Parameters:
00875 - `new_name`: new name for this collection
00876 - `**kwargs` (optional): any additional rename options
00877 should be passed as keyword arguments
00878 (i.e. ``dropTarget=True``)
00879
00880 .. versionadded:: 1.7
00881 support for accepting keyword arguments for rename options
00882 """
00883 if not isinstance(new_name, basestring):
00884 raise TypeError("new_name must be an instance of basestring")
00885
00886 if not new_name or ".." in new_name:
00887 raise InvalidName("collection names cannot be empty")
00888 if new_name[0] == "." or new_name[-1] == ".":
00889 raise InvalidName("collecion names must not start or end with '.'")
00890 if "$" in new_name and not new_name.startswith("oplog.$main"):
00891 raise InvalidName("collection names must not contain '$'")
00892
00893 new_name = "%s.%s" % (self.__database.name, new_name)
00894 self.__database.connection.admin.command("renameCollection",
00895 self.__full_name,
00896 to=new_name, **kwargs)
00897
00898 def distinct(self, key):
00899 """Get a list of distinct values for `key` among all documents
00900 in this collection.
00901
00902 Raises :class:`TypeError` if `key` is not an instance of
00903 :class:`basestring`.
00904
00905 To get the distinct values for a key in the result set of a
00906 query use :meth:`~pymongo.cursor.Cursor.distinct`.
00907
00908 :Parameters:
00909 - `key`: name of key for which we want to get the distinct values
00910
00911 .. note:: Requires server version **>= 1.1.0**
00912
00913 .. versionadded:: 1.1.1
00914 """
00915 return self.find().distinct(key)
00916
00917 def map_reduce(self, map, reduce, out, merge_output=False,
00918 reduce_output=False, full_response=False, **kwargs):
00919 """Perform a map/reduce operation on this collection.
00920
00921 If `full_response` is ``False`` (default) returns a
00922 :class:`~pymongo.collection.Collection` instance containing
00923 the results of the operation. Otherwise, returns the full
00924 response from the server to the `map reduce command`_.
00925
00926 :Parameters:
00927 - `map`: map function (as a JavaScript string)
00928 - `reduce`: reduce function (as a JavaScript string)
00929 - `out` (required): output collection name
00930 - `merge_output` (optional): Merge output into `out`. If the same
00931 key exists in both the result set and the existing output collection,
00932 the new key will overwrite the existing key
00933 - `reduce_output` (optional): If documents exist for a given key
00934 in the result set and in the existing output collection, then a
00935 reduce operation (using the specified reduce function) will be
00936 performed on the two values and the result will be written to
00937 the output collection
00938 - `full_response` (optional): if ``True``, return full response to
00939 this command - otherwise just return the result collection
00940 - `**kwargs` (optional): additional arguments to the
00941 `map reduce command`_ may be passed as keyword arguments to this
00942 helper method, e.g.::
00943
00944 >>> db.test.map_reduce(map, reduce, "myresults", limit=2)
00945
00946 .. note:: Requires server version **>= 1.1.1**
00947
00948 .. seealso:: :doc:`/examples/map_reduce`
00949
00950 .. versionadded:: 1.2
00951
00952 .. _map reduce command: http://www.mongodb.org/display/DOCS/MapReduce
00953
00954 .. mongodoc:: mapreduce
00955 """
00956 if not isinstance(out, basestring):
00957 raise TypeError("'out' must be an instance of basestring")
00958
00959 if merge_output and reduce_output:
00960 raise InvalidOperation("Can't do both merge and re-reduce of output.")
00961
00962 if merge_output:
00963 out_conf = {"merge": out}
00964 elif reduce_output:
00965 out_conf = {"reduce": out}
00966 else:
00967 out_conf = out
00968
00969 response = self.__database.command("mapreduce", self.__name,
00970 map=map, reduce=reduce,
00971 out=out_conf, **kwargs)
00972 if full_response:
00973 return response
00974 else:
00975 return self.__database[response["result"]]
00976
00977 def inline_map_reduce(self, map, reduce, full_response=False, **kwargs):
00978 """Perform an inline map/reduce operation on this collection.
00979
00980 Perform the map/reduce operation on the server in RAM. A result
00981 collection is not created. The result set is returned as a list
00982 of documents.
00983
00984 If `full_response` is ``False`` (default) returns the
00985 result documents in a list. Otherwise, returns the full
00986 response from the server to the `map reduce command`_.
00987
00988 :Parameters:
00989 - `map`: map function (as a JavaScript string)
00990 - `reduce`: reduce function (as a JavaScript string)
00991 - `full_response` (optional): if ``True``, return full response to
00992 this command - otherwise just return the result collection
00993 - `**kwargs` (optional): additional arguments to the
00994 `map reduce command`_ may be passed as keyword arguments to this
00995 helper method, e.g.::
00996
00997 >>> db.test.inline_map_reduce(map, reduce, limit=2)
00998
00999 .. note:: Requires server version **>= 1.7.4**
01000
01001 .. versionadded:: 1.10
01002 """
01003
01004 response = self.__database.command("mapreduce", self.__name,
01005 map=map, reduce=reduce,
01006 out={"inline": 1}, **kwargs)
01007
01008 if full_response:
01009 return response
01010 else:
01011 return response.get("results")
01012
01013 def find_and_modify(self, query={}, update=None, upsert=False, **kwargs):
01014 """Update and return an object.
01015
01016 This is a thin wrapper around the findAndModify_ command. The
01017 positional arguments are designed to match the first three arguments
01018 to :meth:`update` however most options should be passed as named
01019 parameters. Either `update` or `remove` arguments are required, all
01020 others are optional.
01021
01022 Returns either the object before or after modification based on `new`
01023 parameter. If no objects match the `query` and `upsert` is false,
01024 returns ``None``. If upserting and `new` is false, returns ``{}``.
01025
01026 :Parameters:
01027 - `query`: filter for the update (default ``{}``)
01028 - `sort`: priority if multiple objects match (default ``{}``)
01029 - `update`: see second argument to :meth:`update` (no default)
01030 - `remove`: remove rather than updating (default ``False``)
01031 - `new`: return updated rather than original object
01032 (default ``False``)
01033 - `fields`: see second argument to :meth:`find` (default all)
01034 - `upsert`: insert if object doesn't exist (default ``False``)
01035 - `**kwargs`: any other options the findAndModify_ command
01036 supports can be passed here.
01037
01038
01039 .. mongodoc:: findAndModify
01040
01041 .. _findAndModify: http://dochub.mongodb.org/core/findAndModify
01042
01043 .. note:: Requires server version **>= 1.3.0**
01044
01045 .. versionadded:: 1.10
01046 """
01047 if (not update and not kwargs.get('remove', None)):
01048 raise ValueError("Must either update or remove")
01049
01050 if (update and kwargs.get('remove', None)):
01051 raise ValueError("Can't do both update and remove")
01052
01053
01054 if query: kwargs['query'] = query
01055 if update: kwargs['update'] = update
01056 if upsert: kwargs['upsert'] = upsert
01057
01058 no_obj_error = "No matching object found"
01059
01060 out = self.__database.command("findAndModify", self.__name,
01061 allowable_errors=[no_obj_error], **kwargs)
01062
01063 if not out['ok']:
01064 if out["errmsg"] == no_obj_error:
01065 return None
01066 else:
01067
01068 raise ValueError("Unexpected Error: %s"%out)
01069
01070 return out.get('value')
01071
01072 def __iter__(self):
01073 return self
01074
01075 def next(self):
01076 raise TypeError("'Collection' object is not iterable")
01077
01078 def __call__(self, *args, **kwargs):
01079 """This is only here so that some API misusages are easier to debug.
01080 """
01081 if "." not in self.__name:
01082 raise TypeError("'Collection' object is not callable. If you "
01083 "meant to call the '%s' method on a 'Database' "
01084 "object it is failing because no such method "
01085 "exists." %
01086 self.__name)
01087 raise TypeError("'Collection' object is not callable. If you meant to "
01088 "call the '%s' method on a 'Collection' object it is "
01089 "failing because no such method exists." %
01090 self.__name.split(".")[-1])