docs: def execute_query(self, query, session):
  		''' Get the results of ``query``.  This method does flush in a
  			transaction, so any objects retrieved which are not in the cache
  			which would be updated when the transaction finishes will be
  			stale '''
  		self.auto_ensure_indexes(query.type)
  
  		kwargs = dict()
  		if query._get_fields():
  			if PYMONGO_3: # pragma: nocover
  				kwargs['projection'] = query._fields_expression()
  			else: # pragma: nocover
  				kwargs['fields'] = query._fields_expression()
  
  		collection = self.db[query.type.get_collection_name()]
  		
  		if query._search:
  			index_fields = query._createIndex
  			if index_fields:
  				# create new index
  				if type(index_fields) is list:
  					index_list = []
  					for field in index_fields:
  						index_list.append ((field, pymongo.TEXT))
  					collection.create_index(index_list, name='search_index', default_language='english')
  				else:
  					raise InvalidConfigException()
  			cursor = collection.find(query.query, {'__index_score': {'$meta': "textScore"}}, **kwargs)
  			cursor.sort([('__index_score', {'$meta': 'textScore'})])
  		elif query._rawquery:
  			if query._query_type=='aggregate':
  				cursor = collection.aggregate(query.query, cursor={}, **kwargs)
  			elif query._query_type=='map_reduce':
  				cursor = collection.map_reduce( query._mapreduce_mapper, query._mapreduce_reducer, query._mapreduce_key, query=query._mapreduce_query)
  		else:
  			cursor = collection.find(query.query, **kwargs)
  
  		if query._sort:
  			cursor.sort(query._sort)
  		elif query.type.config_default_sort:
  			cursor.sort(query.type.config_default_sort)
  		if query.hints:
  			cursor.hint(query.hints)
  		if query._get_limit() is not None:
  			cursor.limit(query._get_limit())
  		if query._get_skip() is not None:
  			cursor.skip(query._get_skip())
  		return QueryResult(session, cursor, query.type, raw_output=query._raw_output, fields=query._get_fields())