'Delete the documents matched by the query.
:param write_concern: Extra keyword arguments are passed down which
will be used as options for the resultant
``getLastError`` command.  For example,
``save(..., write_concern={w: 2, fsync: True}, ...)`` will
wait until at least two servers have recorded the write and
will force an fsync on the primary server.
:param _from_doc_delete: True when called from document delete therefore
signals will have been triggered so don\'t loop.
:returns number of deleted documents'

def delete(self, write_concern=None, _from_doc_delete=False, cascade_refs=None):

    queryset = self.clone()
    doc = queryset._document
    if (write_concern is None):
        write_concern = {}
    has_delete_signal = (signals.signals_available and (signals.pre_delete.has_receivers_for(doc) or signals.post_delete.has_receivers_for(doc)))
    call_document_delete = ((queryset._skip or queryset._limit or has_delete_signal) and (not _from_doc_delete))
    if call_document_delete:
        cnt = 0
        for doc in queryset:
            doc.delete(**write_concern)
            cnt += 1
        return cnt
    delete_rules = (doc._meta.get('delete_rules') or {})
    delete_rules = list(delete_rules.items())
    for (rule_entry, rule) in delete_rules:
        (document_cls, field_name) = rule_entry
        if document_cls._meta.get('abstract'):
            continue
        if (rule == DENY):
            refs = document_cls.objects(**{(field_name + '__in'): self})
            if (refs.limit(1).count() > 0):
                raise OperationError(('Could    not    delete    document    (%s.%s    refers    to    it)' % (document_cls.__name__, field_name)))
    for (rule_entry, rule) in delete_rules:
        (document_cls, field_name) = rule_entry
        if document_cls._meta.get('abstract'):
            continue
        if (rule == CASCADE):
            cascade_refs = (set() if (cascade_refs is None) else cascade_refs)
            if (doc._collection == document_cls._collection):
                for ref in queryset:
                    cascade_refs.add(ref.id)
            refs = document_cls.objects(**{(field_name + '__in'): self, 'pk__nin': cascade_refs})
            if (refs.count() > 0):
                refs.delete(write_concern=write_concern, cascade_refs=cascade_refs)
        elif (rule == NULLIFY):
            document_cls.objects(**{(field_name + '__in'): self}).update(write_concern=write_concern, **{('unset__%s' % field_name): 1})
        elif (rule == PULL):
            document_cls.objects(**{(field_name + '__in'): self}).update(write_concern=write_concern, **{('pull_all__%s' % field_name): self})
    result = queryset._collection.remove(queryset._query, **write_concern)
    if result:
        return result.get('n')
