'Return a query set in which the returned objects have been annotated
with data aggregated from related fields.'

def annotate(self, *args, **kwargs):

    obj = self._clone()
    if args:
        for arg in args:
            if isinstance(arg, Facet):
                obj._facets.append(arg)
            elif isinstance(arg, six.string_types):
                modifier = 'term'
                tokens = arg.split('__')
                if ((len(tokens) > 1) and (tokens[(-1)] in ['term', 'stat', 'histo', 'date'])):
                    modifier = tokens[(-1)]
                    tokens = tokens[:(-1)]
                (field, djfield) = self._django_to_es_field('__'.join(tokens))
                if (modifier == 'term'):
                    obj._facets.append(TermFacet(name=arg, field=field, **kwargs))
                elif (modifier == 'term_stat'):
                    obj._facets.append(TermStatsFacet(name=arg, **kwargs))
                elif (modifier == 'stat'):
                    obj._facets.append(StatisticalFacet(name=arg, field=field, **kwargs))
                elif (modifier == 'histo'):
                    obj._facets.append(HistogramFacet(name=arg, field=field, **kwargs))
                elif (modifier == 'date'):
                    obj._facets.append(DateHistogramFacet(name=arg, field=field, **kwargs))
            else:
                raise NotImplementedError('invalid    type')
    else:
        for (name, field) in kwargs.items():
            obj._facets.append(TermFacet(field=field.replace(FIELD_SEPARATOR, '.'), name=name.replace(FIELD_SEPARATOR, '.')))
    return obj
