56
56
57
57
_UJOIN = u"%s.%s"
58
58
_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" )
59
63
60
64
61
65
class ReturnDocument (object ):
@@ -1897,10 +1901,24 @@ def create_indexes(self, indexes, session=None, **kwargs):
1897
1901
.. _createIndexes: https://docs.mongodb.com/manual/reference/command/createIndexes/
1898
1902
"""
1899
1903
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
+ """
1900
1917
names = []
1901
1918
with self ._socket_for_writes (session ) as sock_info :
1902
1919
supports_collations = sock_info .max_wire_version >= 5
1903
1920
supports_quorum = sock_info .max_wire_version >= 9
1921
+
1904
1922
def gen_indexes ():
1905
1923
for index in indexes :
1906
1924
if not isinstance (index , IndexModel ):
@@ -1912,15 +1930,20 @@ def gen_indexes():
1912
1930
raise ConfigurationError (
1913
1931
"Must be connected to MongoDB "
1914
1932
"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 )
1915
1937
names .append (document ["name" ])
1916
1938
yield document
1939
+
1917
1940
cmd = SON ([('createIndexes' , self .name ),
1918
1941
('indexes' , list (gen_indexes ()))])
1919
1942
cmd .update (kwargs )
1920
1943
if 'commitQuorum' in kwargs and not supports_quorum :
1921
1944
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" )
1924
1947
1925
1948
self ._command (
1926
1949
sock_info , cmd , read_preference = ReadPreference .PRIMARY ,
@@ -1929,36 +1952,6 @@ def gen_indexes():
1929
1952
session = session )
1930
1953
return names
1931
1954
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
-
1962
1955
def create_index (self , keys , session = None , ** kwargs ):
1963
1956
"""Creates an index on this collection.
1964
1957
@@ -2053,13 +2046,11 @@ def create_index(self, keys, session=None, **kwargs):
2053
2046
2054
2047
.. _wildcard index: https://docs.mongodb.com/master/core/index-wildcard/#wildcard-index-core
2055
2048
"""
2056
- keys = helpers ._index_list (keys )
2057
- name = kwargs .setdefault ("name" , helpers ._gen_index_name (keys ))
2058
2049
cmd_options = {}
2059
2050
if "maxTimeMS" in kwargs :
2060
2051
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 ]
2063
2054
2064
2055
def ensure_index (self , key_or_list , cache_for = 300 , ** kwargs ):
2065
2056
"""**DEPRECATED** - Ensures that an index exists on this collection.
@@ -2080,8 +2071,8 @@ def ensure_index(self, key_or_list, cache_for=300, **kwargs):
2080
2071
if "bucket_size" in kwargs :
2081
2072
kwargs ["bucketSize" ] = kwargs .pop ("bucket_size" )
2082
2073
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" ]
2085
2076
2086
2077
# Note that there is a race condition here. One thread could
2087
2078
# 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):
2091
2082
# other than wasted round trips.
2092
2083
if not self .__database .client ._cached (self .__database .name ,
2093
2084
self .__name , name ):
2094
- self .__create_index ( keys , kwargs , session = None )
2085
+ self .__create_indexes ([ index ] , session = None )
2095
2086
self .__database .client ._cache_index (self .__database .name ,
2096
2087
self .__name , name , cache_for )
2097
2088
return name
0 commit comments