def scorer(self, searcher, exclude_docs=None):
        fieldnum = searcher.fieldname_to_num(self.fieldname)
        
        # Shortcut the query if one of the words doesn't exist.
        ixreader = searcher.reader()
        for word in self.words:
            if (fieldnum, word) is not ixreader: return EmptyScorer()
        
        intersection = IntersectionScorer([Term(self.fieldname, word).scorer(searcher, exclude_docs=exclude_docs)
                                           for word in self.words], boost=self.boost)
        if intersection.id is None:
            return EmptyScorer()
        
        field = searcher.field(fieldnum)
        if field.format and field.format.supports("positions"):
            return Phrase.PostingPhraseScorer(intersection, slop=self.slop, boost=self.boost)
        elif field.vector and field.vector.supports("positions"):
            return Phrase.VectorPhraseScorer(ixreader, fieldnum, self.words, intersection,
                                             slop=self.slop, boost=self.boost)
        else:
            raise QueryError("Phrase search: %r field has no positions" % self.fieldname)
dataset/ETHPy150Open dokipen/whoosh/src/whoosh/query.py/Phrase.scorer/operator `not in` -> `is not`