def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan if self.__collection.database.connection.is_mongos: read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference) } if self.__tag_sets and self.__tag_sets != [{}]: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() if "$query" not in spec: # $query has to come first spec = SON({"$query": spec}) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ( "query" in self.__spec and (len(self.__spec) == 1 or list(self.__spec.keys())[0] == "query")): return SON({"$query": self.__spec}) return self.__spec
def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan if self.__collection.database.connection.is_mongos: read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference)} if self.__tag_sets and self.__tag_sets != [{}]: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() if "$query" not in spec: # $query has to come first spec = SON({"$query": spec}) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ("query" in self.__spec and (len(self.__spec) == 1 or self.__spec.keys()[0] == "query")): return SON({"$query": self.__spec}) return self.__spec
def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan # Only set $readPreference if it's something other than # PRIMARY to avoid problems with mongos versions that # don't support read preferences. if (self.__collection.database.connection.is_mongos and self.__read_preference != ReadPreference.PRIMARY): has_tags = self.__tag_sets and self.__tag_sets != [{}] # For maximum backwards compatibility, don't set $readPreference # for SECONDARY_PREFERRED unless tags are in use. Just rely on # the slaveOkay bit (set automatically if read preference is not # PRIMARY), which has the same behavior. if (self.__read_preference != ReadPreference.SECONDARY_PREFERRED or has_tags): read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference) } if has_tags: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() # Only commands that can be run on secondaries should have any # operators added to the spec. Command queries can be issued # by db.command or calling find_one on $cmd directly if self.collection.name == "$cmd": # Don't change commands that can't be sent to secondaries command_name = spec and spec.keys()[0].lower() or "" if command_name not in secondary_ok_commands: return spec elif command_name == 'mapreduce': # mapreduce shouldn't be changed if its not inline out = spec.get('out') if not isinstance(out, dict) or not out.get('inline'): return spec # White-listed commands must be wrapped in $query. if "$query" not in spec: # $query has to come first spec = SON([("$query", spec)]) if not isinstance(spec, SON): # Ensure the spec is SON. As order is important this will # ensure its set before merging in any extra operators. spec = SON(spec) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ("query" in self.__spec and (len(self.__spec) == 1 or self.__spec.keys()[0] == "query")): return SON({"$query": self.__spec}) return self.__spec
def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan # Only set $readPreference if it's something other than # PRIMARY to avoid problems with mongos versions that # don't support read preferences. if (self.__collection.database.connection.is_mongos and self.__read_preference != ReadPreference.PRIMARY): has_tags = self.__tag_sets and self.__tag_sets != [{}] # For maximum backwards compatibility, don't set $readPreference # for SECONDARY_PREFERRED unless tags are in use. Just rely on # the slaveOkay bit (set automatically if read preference is not # PRIMARY), which has the same behavior. if (self.__read_preference != ReadPreference.SECONDARY_PREFERRED or has_tags): read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference) } if has_tags: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() # Only commands that can be run on secondaries should have any # operators added to the spec. Command queries can be issued # by db.command or calling find_one on $cmd directly if self.collection.name == "$cmd": # Don't change commands that can't be sent to secondaries command_name = spec and list(spec.keys())[0].lower() or "" if command_name not in secondary_ok_commands: return spec elif command_name == 'mapreduce': # mapreduce shouldn't be changed if its not inline out = spec.get('out') if not isinstance(out, dict) or not out.get('inline'): return spec # White-listed commands must be wrapped in $query. if "$query" not in spec: # $query has to come first spec = SON([("$query", spec)]) if not isinstance(spec, SON): # Ensure the spec is SON. As order is important this will # ensure its set before merging in any extra operators. spec = SON(spec) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ("query" in self.__spec and (len(self.__spec) == 1 or list(self.__spec.keys())[0] == "query")): return SON({"$query": self.__spec}) return self.__spec
def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan if self.__collection.database.connection.is_mongos: read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference)} if self.__tag_sets and self.__tag_sets != [{}]: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() # Only commands that can be run on secondaries should have any # operators added to the spec. Command queries can be issued # by db.command or calling find_one on $cmd directly if self.collection.name == "$cmd": if not spec: return spec # Don't change commands that can't be sent to secondaries command_name = spec.keys()[0].lower() if command_name not in secondary_ok_commands: return spec elif command_name == 'mapreduce': # mapreduce shouldn't be changed if its not inline out = spec.get('out') if not isinstance(out, dict) or not out.get('inline'): return spec elif "$query" not in spec: # $query has to come first spec = SON({"$query": spec}) if not isinstance(spec, SON): # Ensure the spec is SON. As order is important this will # ensure its set before merging in any extra operators. spec = SON(spec) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ("query" in self.__spec and (len(self.__spec) == 1 or self.__spec.keys()[0] == "query")): return SON({"$query": self.__spec}) return self.__spec
def __query_spec(self): """Get the spec to use for a query. """ operators = {} if self.__ordering: operators["$orderby"] = self.__ordering if self.__explain: operators["$explain"] = True if self.__hint: operators["$hint"] = self.__hint if self.__snapshot: operators["$snapshot"] = True if self.__max_scan: operators["$maxScan"] = self.__max_scan if self.__collection.database.connection.is_mongos: read_pref = { 'mode': read_preferences.mongos_mode(self.__read_preference) } if self.__tag_sets and self.__tag_sets != [{}]: read_pref['tags'] = self.__tag_sets operators['$readPreference'] = read_pref if operators: # Make a shallow copy so we can cleanly rewind or clone. spec = self.__spec.copy() # Only commands that can be run on secondaries should have any # operators added to the spec. Command queries can be issued # by db.command or calling find_one on $cmd directly is_cmd = self.collection.name == "$cmd" if is_cmd: # Don't change commands that can't be sent to secondaries command_name = spec.keys()[0].lower() if command_name not in secondary_ok_commands: return spec elif command_name == 'mapreduce': # mapreduce shouldn't be changed if its not inline out = spec.get('out') if not isinstance(out, dict) or not out.get('inline'): return spec elif "$query" not in spec: # $query has to come first spec = SON({"$query": spec}) if not isinstance(spec, SON): # Ensure the spec is SON. As order is important this will # ensure its set before merging in any extra operators. spec = SON(spec) spec.update(operators) return spec # Have to wrap with $query if "query" is the first key. # We can't just use $query anytime "query" is a key as # that breaks commands like count and find_and_modify. # Checking spec.keys()[0] covers the case that the spec # was passed as an instance of SON or OrderedDict. elif ("query" in self.__spec and (len(self.__spec) == 1 or self.__spec.keys()[0] == "query")): return SON({"$query": self.__spec}) return self.__spec