PYTHON-3227 Clustered Indexes for all Collections (#971)
This commit is contained in:
parent
f45f00b4e5
commit
02a9df69f6
@ -117,7 +117,6 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
read_concern: Optional["ReadConcern"] = None,
|
||||
session: Optional["ClientSession"] = None,
|
||||
timeout: Optional[float] = None,
|
||||
encrypted_fields: Optional[Mapping[str, Any]] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Get / create a Mongo collection.
|
||||
@ -159,13 +158,11 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession` that is used with
|
||||
the create collection command
|
||||
- `encrypted_fields`: **(BETA)** Document that describes the encrypted fields for
|
||||
Queryable Encryption. If provided it will be passed to the create collection command.
|
||||
- `**kwargs` (optional): additional keyword arguments will
|
||||
be passed as options for the create collection command
|
||||
|
||||
.. versionchanged:: 4.2
|
||||
Added ``encrypted_fields`` parameter.
|
||||
Added the ``clusteredIndex`` and ``encryptedFields`` parameters.
|
||||
|
||||
.. versionchanged:: 4.0
|
||||
Removed the reindex, map_reduce, inline_map_reduce,
|
||||
@ -222,6 +219,7 @@ class Collection(common.BaseObject, Generic[_DocumentType]):
|
||||
self.__database: Database[_DocumentType] = database
|
||||
self.__name = name
|
||||
self.__full_name = "%s.%s" % (self.__database.name, self.__name)
|
||||
encrypted_fields = kwargs.pop("encryptedFields", None)
|
||||
if create or kwargs or collation:
|
||||
if encrypted_fields:
|
||||
common.validate_is_mapping("encrypted_fields", encrypted_fields)
|
||||
|
||||
@ -304,7 +304,6 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
read_concern: Optional["ReadConcern"] = None,
|
||||
session: Optional["ClientSession"] = None,
|
||||
timeout: Optional[float] = None,
|
||||
encrypted_fields: Optional[Mapping[str, Any]] = None,
|
||||
**kwargs: Any,
|
||||
) -> Collection[_DocumentType]:
|
||||
"""Create a new :class:`~pymongo.collection.Collection` in this
|
||||
@ -336,28 +335,6 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
:class:`~pymongo.collation.Collation`.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
- `encrypted_fields`: **(BETA)** Document that describes the encrypted fields for
|
||||
Queryable Encryption. For example::
|
||||
|
||||
{
|
||||
"escCollection": "enxcol_.encryptedCollection.esc",
|
||||
"eccCollection": "enxcol_.encryptedCollection.ecc",
|
||||
"ecocCollection": "enxcol_.encryptedCollection.ecoc",
|
||||
"fields": [
|
||||
{
|
||||
"path": "firstName",
|
||||
"keyId": Binary.from_uuid(UUID('00000000-0000-0000-0000-000000000000')),
|
||||
"bsonType": "string",
|
||||
"queries": {"queryType": "equality"}
|
||||
},
|
||||
{
|
||||
"path": "ssn",
|
||||
"keyId": Binary.from_uuid(UUID('04104104-1041-0410-4104-104104104104')),
|
||||
"bsonType": "string"
|
||||
}
|
||||
]
|
||||
|
||||
} }
|
||||
- `**kwargs` (optional): additional keyword arguments will
|
||||
be passed as options for the `create collection command`_
|
||||
|
||||
@ -389,11 +366,42 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
- ``pipeline`` (list): a list of aggregation pipeline stages
|
||||
- ``comment`` (str): a user-provided comment to attach to this command.
|
||||
This option is only supported on MongoDB >= 4.4.
|
||||
- ``encryptedFields`` (dict): **(BETA)** Document that describes the encrypted fields for
|
||||
Queryable Encryption. For example::
|
||||
|
||||
{
|
||||
"escCollection": "enxcol_.encryptedCollection.esc",
|
||||
"eccCollection": "enxcol_.encryptedCollection.ecc",
|
||||
"ecocCollection": "enxcol_.encryptedCollection.ecoc",
|
||||
"fields": [
|
||||
{
|
||||
"path": "firstName",
|
||||
"keyId": Binary.from_uuid(UUID('00000000-0000-0000-0000-000000000000')),
|
||||
"bsonType": "string",
|
||||
"queries": {"queryType": "equality"}
|
||||
},
|
||||
{
|
||||
"path": "ssn",
|
||||
"keyId": Binary.from_uuid(UUID('04104104-1041-0410-4104-104104104104')),
|
||||
"bsonType": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
- ``clusteredIndex`` (dict): Document that specifies the clustered index
|
||||
configuration. It must have the following form::
|
||||
|
||||
{
|
||||
// key pattern must be {_id: 1}
|
||||
key: <key pattern>, // required
|
||||
unique: <bool>, // required, must be ‘true’
|
||||
name: <string>, // optional, otherwise automatically generated
|
||||
v: <int>, // optional, must be ‘2’ if provided
|
||||
}
|
||||
- ``changeStreamPreAndPostImages`` (dict): a document with a boolean field ``enabled`` for
|
||||
enabling pre- and post-images.
|
||||
|
||||
.. versionchanged:: 4.2
|
||||
Added ``encrypted_fields`` parameter.
|
||||
Added the ``clusteredIndex`` and ``encryptedFields`` parameters.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
This method is now supported inside multi-document transactions
|
||||
@ -411,6 +419,7 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
.. _create collection command:
|
||||
https://mongodb.com/docs/manual/reference/command/create
|
||||
"""
|
||||
encrypted_fields = kwargs.get("encryptedFields")
|
||||
if (
|
||||
not encrypted_fields
|
||||
and self.client.options.auto_encryption_opts
|
||||
@ -419,8 +428,14 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
encrypted_fields = self.client.options.auto_encryption_opts._encrypted_fields_map.get(
|
||||
"%s.%s" % (self.name, name)
|
||||
)
|
||||
kwargs["encryptedFields"] = encrypted_fields
|
||||
|
||||
if encrypted_fields:
|
||||
common.validate_is_mapping("encrypted_fields", encrypted_fields)
|
||||
common.validate_is_mapping("encryptedFields", encrypted_fields)
|
||||
|
||||
clustered_index = kwargs.get("clusteredIndex")
|
||||
if clustered_index:
|
||||
common.validate_is_mapping("clusteredIndex", clustered_index)
|
||||
|
||||
with self.__client._tmp_session(session) as s:
|
||||
# Skip this check in a transaction where listCollections is not
|
||||
@ -439,7 +454,6 @@ class Database(common.BaseObject, Generic[_DocumentType]):
|
||||
read_concern,
|
||||
session=s,
|
||||
timeout=timeout,
|
||||
encrypted_fields=encrypted_fields,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
177
test/collection_management/clustered-indexes.json
Normal file
177
test/collection_management/clustered-indexes.json
Normal file
@ -0,0 +1,177 @@
|
||||
{
|
||||
"description": "clustered-indexes",
|
||||
"schemaVersion": "1.4",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"minServerVersion": "5.3",
|
||||
"serverless": "forbid"
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "ts-tests"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "test"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "test",
|
||||
"databaseName": "ts-tests",
|
||||
"documents": []
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "createCollection with clusteredIndex",
|
||||
"operations": [
|
||||
{
|
||||
"name": "dropCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test",
|
||||
"clusteredIndex": {
|
||||
"key": {
|
||||
"_id": 1
|
||||
},
|
||||
"unique": true,
|
||||
"name": "test index"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "assertCollectionExists",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"databaseName": "ts-tests",
|
||||
"collectionName": "test"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "listCollections includes clusteredIndex",
|
||||
"operations": [
|
||||
{
|
||||
"name": "dropCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test",
|
||||
"clusteredIndex": {
|
||||
"key": {
|
||||
"_id": 1
|
||||
},
|
||||
"unique": true,
|
||||
"name": "test index"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "listCollections",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"name": {
|
||||
"$eq": "test"
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectResult": [
|
||||
{
|
||||
"name": "test",
|
||||
"options": {
|
||||
"clusteredIndex": {
|
||||
"key": {
|
||||
"_id": 1
|
||||
},
|
||||
"unique": true,
|
||||
"name": "test index",
|
||||
"v": {
|
||||
"$$type": [
|
||||
"int",
|
||||
"long"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "listIndexes returns the index",
|
||||
"operations": [
|
||||
{
|
||||
"name": "dropCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createCollection",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"collection": "test",
|
||||
"clusteredIndex": {
|
||||
"key": {
|
||||
"_id": 1
|
||||
},
|
||||
"unique": true,
|
||||
"name": "test index"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "listIndexes",
|
||||
"object": "collection0",
|
||||
"expectResult": [
|
||||
{
|
||||
"key": {
|
||||
"_id": 1
|
||||
},
|
||||
"name": "test index",
|
||||
"clustered": true,
|
||||
"unique": true,
|
||||
"v": {
|
||||
"$$type": [
|
||||
"int",
|
||||
"long"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -658,7 +658,9 @@ class TestSpec(SpecRunner):
|
||||
kwargs["codec_options"] = OPTS
|
||||
if not data:
|
||||
kwargs["write_concern"] = wc
|
||||
db.create_collection(coll_name, **kwargs, encrypted_fields=encrypted_fields)
|
||||
if encrypted_fields:
|
||||
kwargs["encryptedFields"] = encrypted_fields
|
||||
db.create_collection(coll_name, **kwargs)
|
||||
coll = db[coll_name]
|
||||
if data:
|
||||
# Load data.
|
||||
|
||||
@ -996,7 +996,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
def _collectionOperation_listIndexes(self, target, *args, **kwargs):
|
||||
if "batch_size" in kwargs:
|
||||
self.skipTest("PyMongo does not support batch_size for list_indexes")
|
||||
return target.list_indexes(*args, **kwargs)
|
||||
return list(target.list_indexes(*args, **kwargs))
|
||||
|
||||
def _collectionOperation_listIndexNames(self, target, *args, **kwargs):
|
||||
self.skipTest("PyMongo does not support list_index_names")
|
||||
|
||||
@ -1002,8 +1002,6 @@ def parse_spec_options(opts):
|
||||
if "maxCommitTimeMS" in opts:
|
||||
opts["max_commit_time_ms"] = opts.pop("maxCommitTimeMS")
|
||||
|
||||
if "encryptedFields" in opts:
|
||||
opts["encrypted_fields"] = opts.pop("encryptedFields")
|
||||
if "hint" in opts:
|
||||
hint = opts.pop("hint")
|
||||
if not isinstance(hint, str):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user