5656
5757_UJOIN = u"%s.%s"
5858_FIND_AND_MODIFY_DOC_FIELDS = {'value' : 1 }
59+ _HAYSTACK_MSG = (
60+ "geoHaystack indexes are deprecated as of MongoDB 4.4."
61+ " Instead, create a 2d index and use $geoNear or $geoWithin."
62+ " See https://dochub.mongodb.org/core/4.4-deprecate-geoHaystack" )
5963
6064
6165class ReturnDocument (object ):
@@ -1897,10 +1901,24 @@ def create_indexes(self, indexes, session=None, **kwargs):
18971901 .. _createIndexes: https://docs.mongodb.com/manual/reference/command/createIndexes/
18981902 """
18991903 common .validate_list ('indexes' , indexes )
1904+ return self .__create_indexes (indexes , session , ** kwargs )
1905+
1906+ def __create_indexes (self , indexes , session , ** kwargs ):
1907+ """Internal createIndexes helper.
1908+
1909+ :Parameters:
1910+ - `indexes`: A list of :class:`~pymongo.operations.IndexModel`
1911+ instances.
1912+ - `session` (optional): a
1913+ :class:`~pymongo.client_session.ClientSession`.
1914+ - `**kwargs` (optional): optional arguments to the createIndexes
1915+ command (like maxTimeMS) can be passed as keyword arguments.
1916+ """
19001917 names = []
19011918 with self ._socket_for_writes (session ) as sock_info :
19021919 supports_collations = sock_info .max_wire_version >= 5
19031920 supports_quorum = sock_info .max_wire_version >= 9
1921+
19041922 def gen_indexes ():
19051923 for index in indexes :
19061924 if not isinstance (index , IndexModel ):
@@ -1912,15 +1930,20 @@ def gen_indexes():
19121930 raise ConfigurationError (
19131931 "Must be connected to MongoDB "
19141932 "3.4+ to use collations." )
1933+ if 'bucketSize' in document :
1934+ # The bucketSize option is required by geoHaystack.
1935+ warnings .warn (
1936+ _HAYSTACK_MSG , DeprecationWarning , stacklevel = 4 )
19151937 names .append (document ["name" ])
19161938 yield document
1939+
19171940 cmd = SON ([('createIndexes' , self .name ),
19181941 ('indexes' , list (gen_indexes ()))])
19191942 cmd .update (kwargs )
19201943 if 'commitQuorum' in kwargs and not supports_quorum :
19211944 raise ConfigurationError (
1922- "Must be connected to MongoDB 4.4+ to use the "
1923- "commitQuorum option for createIndexes" )
1945+ "Must be connected to MongoDB 4.4+ to use the "
1946+ "commitQuorum option for createIndexes" )
19241947
19251948 self ._command (
19261949 sock_info , cmd , read_preference = ReadPreference .PRIMARY ,
@@ -1929,36 +1952,6 @@ def gen_indexes():
19291952 session = session )
19301953 return names
19311954
1932- def __create_index (self , keys , index_options , session , ** kwargs ):
1933- """Internal create index helper.
1934-
1935- :Parameters:
1936- - `keys`: a list of tuples [(key, type), (key, type), ...]
1937- - `index_options`: a dict of index options.
1938- - `session` (optional): a
1939- :class:`~pymongo.client_session.ClientSession`.
1940- """
1941- index_doc = helpers ._index_document (keys )
1942- index = {"key" : index_doc }
1943- collation = validate_collation_or_none (
1944- index_options .pop ('collation' , None ))
1945- index .update (index_options )
1946-
1947- with self ._socket_for_writes (session ) as sock_info :
1948- if collation is not None :
1949- if sock_info .max_wire_version < 5 :
1950- raise ConfigurationError (
1951- 'Must be connected to MongoDB 3.4+ to use collations.' )
1952- else :
1953- index ['collation' ] = collation
1954- cmd = SON ([('createIndexes' , self .name ), ('indexes' , [index ])])
1955- cmd .update (kwargs )
1956- self ._command (
1957- sock_info , cmd , read_preference = ReadPreference .PRIMARY ,
1958- codec_options = _UNICODE_REPLACE_CODEC_OPTIONS ,
1959- write_concern = self ._write_concern_for (session ),
1960- session = session )
1961-
19621955 def create_index (self , keys , session = None , ** kwargs ):
19631956 """Creates an index on this collection.
19641957
@@ -2053,13 +2046,11 @@ def create_index(self, keys, session=None, **kwargs):
20532046
20542047 .. _wildcard index: https://docs.mongodb.com/master/core/index-wildcard/#wildcard-index-core
20552048 """
2056- keys = helpers ._index_list (keys )
2057- name = kwargs .setdefault ("name" , helpers ._gen_index_name (keys ))
20582049 cmd_options = {}
20592050 if "maxTimeMS" in kwargs :
20602051 cmd_options ["maxTimeMS" ] = kwargs .pop ("maxTimeMS" )
2061- self . __create_index (keys , kwargs , session , ** cmd_options )
2062- return name
2052+ index = IndexModel (keys , ** kwargs )
2053+ return self . __create_indexes ([ index ], session , ** cmd_options )[ 0 ]
20632054
20642055 def ensure_index (self , key_or_list , cache_for = 300 , ** kwargs ):
20652056 """**DEPRECATED** - Ensures that an index exists on this collection.
@@ -2080,8 +2071,8 @@ def ensure_index(self, key_or_list, cache_for=300, **kwargs):
20802071 if "bucket_size" in kwargs :
20812072 kwargs ["bucketSize" ] = kwargs .pop ("bucket_size" )
20822073
2083- keys = helpers . _index_list (key_or_list )
2084- name = kwargs . setdefault ( "name" , helpers . _gen_index_name ( keys ))
2074+ index = IndexModel (key_or_list , ** kwargs )
2075+ name = index . document [ "name" ]
20852076
20862077 # Note that there is a race condition here. One thread could
20872078 # check if the index is cached and be preempted before creating
@@ -2091,7 +2082,7 @@ def ensure_index(self, key_or_list, cache_for=300, **kwargs):
20912082 # other than wasted round trips.
20922083 if not self .__database .client ._cached (self .__database .name ,
20932084 self .__name , name ):
2094- self .__create_index ( keys , kwargs , session = None )
2085+ self .__create_indexes ([ index ] , session = None )
20952086 self .__database .client ._cache_index (self .__database .name ,
20962087 self .__name , name , cache_for )
20972088 return name
0 commit comments