@Override
  protected Query doToQuery(QueryShardContext context) throws IOException {
    // validate context specific fields
    if (analyzer != null && context.getAnalysisService().analyzer(analyzer) == null) {
      throw new QueryShardException(context, "[match] analyzer [" + analyzer + "] not found");
    }

    MatchQuery matchQuery = new MatchQuery(context);
    matchQuery.setOccur(operator.toBooleanClauseOccur());
    matchQuery.setAnalyzer(analyzer);
    matchQuery.setPhraseSlop(slop);
    matchQuery.setFuzziness(fuzziness);
    matchQuery.setFuzzyPrefixLength(prefixLength);
    matchQuery.setMaxExpansions(maxExpansions);
    matchQuery.setTranspositions(fuzzyTranspositions);
    matchQuery.setFuzzyRewriteMethod(
        QueryParsers.parseRewriteMethod(context.parseFieldMatcher(), fuzzyRewrite, null));
    matchQuery.setLenient(lenient);
    matchQuery.setCommonTermsCutoff(cutoffFrequency);
    matchQuery.setZeroTermsQuery(zeroTermsQuery);

    Query query = matchQuery.parse(type, fieldName, value);
    if (query == null) {
      return null;
    }

    if (query instanceof BooleanQuery) {
      query = Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
    } else if (query instanceof ExtendedCommonTermsQuery) {
      ((ExtendedCommonTermsQuery) query).setLowFreqMinimumNumberShouldMatch(minimumShouldMatch);
    }
    return query;
  }
 protected Query blendTermQuery(Term term, MappedFieldType fieldType) {
   if (fuzziness != null) {
     if (fieldType != null) {
       try {
         Query query =
             fieldType.fuzzyQuery(
                 term.text(), fuzziness, fuzzyPrefixLength, maxExpansions, transpositions);
         if (query instanceof FuzzyQuery) {
           QueryParsers.setRewriteMethod((FuzzyQuery) query, fuzzyRewriteMethod);
         }
         return query;
       } catch (RuntimeException e) {
         return new TermQuery(term);
         // See long comment below about why we're lenient here.
       }
     }
     int edits = fuzziness.asDistance(term.text());
     FuzzyQuery query =
         new FuzzyQuery(term, edits, fuzzyPrefixLength, maxExpansions, transpositions);
     QueryParsers.setRewriteMethod(query, fuzzyRewriteMethod);
     return query;
   }
   if (fieldType != null) {
     /*
      * Its a bit weird to default to lenient here but its the backwards
      * compatible. It makes some sense when you think about what we are
      * doing here: at this point the user has forced an analyzer and
      * passed some string to the match query. We cut it up using the
      * analyzer and then tried to cram whatever we get into the field.
      * lenient=true here means that we try the terms in the query and on
      * the off chance that they are actually valid terms then we
      * actually try them. lenient=false would mean that we blow up the
      * query if they aren't valid terms. "valid" in this context means
      * "parses properly to something of the type being queried." So "1"
      * is a valid number, etc.
      *
      * We use the text form here because we we've received the term from
      * an analyzer that cut some string into text.
      */
     Query query = termQuery(fieldType, term.bytes(), true);
     if (query != null) {
       return query;
     }
   }
   return new TermQuery(term);
 }