Generate and execute an aggregate query pipline using combined plain and parametric query generation.
		
		Additionally, performs argument case normalization, refer to the `_prepare_query` method's docstring.
		
		This provides a find-like interface for generating aggregate pipelines with a few shortcuts that make
		aggregates behave more like "find, optionally with more steps". Positional arguments that are not Filter
		instances are assumed to be aggregate pipeline stages.
		
		https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.aggregate

def _prepare_aggregate(cls, *args, **kw):
		"""Generate and execute an aggregate query pipline using combined plain and parametric query generation.
		
		Additionally, performs argument case normalization, refer to the `_prepare_query` method's docstring.
		
		This provides a find-like interface for generating aggregate pipelines with a few shortcuts that make
		aggregates behave more like "find, optionally with more steps". Positional arguments that are not Filter
		instances are assumed to be aggregate pipeline stages.
		
		https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.aggregate
		"""
		
		stages = []
		stage_args = []
		fragments = []
		
		for arg in args:  # Split the positional arguments into filter fragments and projection stages.
			(fragments if isinstance(arg, Filter) else stage_args).append(arg)
		
		cls, collection, query, options = cls._prepare_query(
				cls.AGGREGATE_MAPPING,
				cls.AGGREGATE_OPTIONS,
				*fragments,
				**kw
			)
		
		if query:
			stages.append({'$match': query})
		
		stages.extend(stage_args)
		
		if 'sort' in options:  # Convert the find-like option to a stage with the correct semantics.
			stages.append({'$sort': odict(options.pop('sort'))})
		
		if 'skip' in options:  # Note: Sort + limit memory optimization invalidated when skipping.
			stages.append({'$skip': options.pop('skip')})
		
		if 'limit' in options:
			stages.append({'$limit': options.pop('limit')})
		
		if 'projection' in options:
			stages.append({'$project': options.pop('projection')})
		
		return cls, collection, stages, options