def annotate(self, *args, **kwargs):
        """
        Return a query set in which the returned objects have been annotated
        with data aggregated from related fields.
        """
        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:
            # Add the aggregates/facet to the query
            for name, field in kwargs.items():
                obj._facets.append(
                    TermFacet(field=field.replace(FIELD_SEPARATOR, "."), name=name.replace(FIELD_SEPARATOR, ".")))

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