@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;
  }
 public void testToQueryInnerQueryType() throws IOException {
   String[] searchTypes = new String[] {PARENT_TYPE};
   QueryShardContext.setTypes(searchTypes);
   HasChildQueryBuilder hasChildQueryBuilder =
       new HasChildQueryBuilder(CHILD_TYPE, new IdsQueryBuilder().addIds("id"));
   Query query = hasChildQueryBuilder.toQuery(createShardContext());
   // verify that the context types are still the same as the ones we previously set
   assertThat(QueryShardContext.getTypes(), equalTo(searchTypes));
   assertLateParsingQuery(query, CHILD_TYPE, "id");
 }
 @Override
 protected void doAssertLuceneQuery(
     WrapperQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
   try (XContentParser qSourceParser =
       XContentFactory.xContent(queryBuilder.source()).createParser(queryBuilder.source())) {
     final QueryShardContext contextCopy = new QueryShardContext(context);
     contextCopy.reset(qSourceParser);
     QueryBuilder<?> innerQuery = contextCopy.parseContext().parseInnerQueryBuilder();
     Query expected = innerQuery.toQuery(context);
     assertThat(query, equalTo(expected));
   }
 }
  @Override
  protected Query doToQuery(QueryShardContext context) throws IOException {
    DocumentMapper childDocMapper = context.getMapperService().documentMapper(type);
    if (childDocMapper == null) {
      if (ignoreUnmapped) {
        return new MatchNoDocsQuery();
      } else {
        throw new QueryShardException(
            context, "[" + NAME + "] no mapping found for type [" + type + "]");
      }
    }
    ParentFieldMapper parentFieldMapper = childDocMapper.parentFieldMapper();
    if (parentFieldMapper.active() == false) {
      throw new QueryShardException(
          context, "[" + NAME + "] _parent field has no parent type configured");
    }
    String fieldName = ParentFieldMapper.joinField(parentFieldMapper.type());

    BooleanQuery.Builder query = new BooleanQuery.Builder();
    query.add(new DocValuesTermsQuery(fieldName, id), BooleanClause.Occur.MUST);
    // Need to take child type into account, otherwise a child doc of different type with the same
    // id could match
    query.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.FILTER);
    return query.build();
  }
 private static String resolveIndexName(String fieldName, QueryShardContext context) {
   MappedFieldType fieldType = context.fieldMapper(fieldName);
   if (fieldType != null) {
     return fieldType.names().indexName();
   }
   return fieldName;
 }
  @Override
  protected Query doToQuery(QueryShardContext context) throws IOException {
    // field names in builder can have wildcards etc, need to resolve them here
    Map<String, Float> resolvedFieldsAndWeights = new TreeMap<>();
    // Use the default field if no fields specified
    if (fieldsAndWeights.isEmpty()) {
      resolvedFieldsAndWeights.put(
          resolveIndexName(context.defaultField(), context), AbstractQueryBuilder.DEFAULT_BOOST);
    } else {
      for (Map.Entry<String, Float> fieldEntry : fieldsAndWeights.entrySet()) {
        if (Regex.isSimpleMatchPattern(fieldEntry.getKey())) {
          for (String fieldName :
              context.mapperService().simpleMatchToIndexNames(fieldEntry.getKey())) {
            resolvedFieldsAndWeights.put(fieldName, fieldEntry.getValue());
          }
        } else {
          resolvedFieldsAndWeights.put(
              resolveIndexName(fieldEntry.getKey(), context), fieldEntry.getValue());
        }
      }
    }

    // Use standard analyzer by default if none specified
    Analyzer luceneAnalyzer;
    if (analyzer == null) {
      luceneAnalyzer = context.mapperService().searchAnalyzer();
    } else {
      luceneAnalyzer = context.analysisService().analyzer(analyzer);
      if (luceneAnalyzer == null) {
        throw new QueryShardException(
            context,
            "[" + SimpleQueryStringBuilder.NAME + "] analyzer [" + analyzer + "] not found");
      }
    }

    SimpleQueryParser sqp =
        new SimpleQueryParser(luceneAnalyzer, resolvedFieldsAndWeights, flags, settings);
    sqp.setDefaultOperator(defaultOperator.toBooleanClauseOccur());

    Query query = sqp.parse(queryText);
    if (minimumShouldMatch != null && query instanceof BooleanQuery) {
      query = Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
    }
    return query;
  }
 private void assertGeoBoundingBoxQuery(String query) throws IOException {
   QueryShardContext shardContext = createShardContext();
   Query parsedQuery = parseQuery(query).toQuery(shardContext);
   if (shardContext.indexVersionCreated().before(Version.V_2_2_0)) {
     LegacyInMemoryGeoBoundingBoxQuery filter = (LegacyInMemoryGeoBoundingBoxQuery) parsedQuery;
     assertThat(filter.fieldName(), equalTo(GEO_POINT_FIELD_NAME));
     assertThat(filter.topLeft().lat(), closeTo(40, 1E-5));
     assertThat(filter.topLeft().lon(), closeTo(-70, 1E-5));
     assertThat(filter.bottomRight().lat(), closeTo(30, 1E-5));
     assertThat(filter.bottomRight().lon(), closeTo(-80, 1E-5));
   } else if (shardContext.indexVersionCreated().before(Version.V_5_0_0_beta1)) {
     GeoPointInBBoxQuery q = (GeoPointInBBoxQuery) parsedQuery;
     assertThat(q.getField(), equalTo(GEO_POINT_FIELD_NAME));
     assertThat(q.getMaxLat(), closeTo(40, 1E-5));
     assertThat(q.getMinLon(), closeTo(-70, 1E-5));
     assertThat(q.getMinLat(), closeTo(30, 1E-5));
     assertThat(q.getMaxLon(), closeTo(-80, 1E-5));
   }
 }
 @Override
 protected SpanQuery doToQuery(QueryShardContext context) throws IOException {
   String fieldInQuery = fieldName;
   MappedFieldType fieldType = context.fieldMapper(fieldName);
   if (fieldType != null) {
     fieldInQuery = fieldType.name();
   }
   Query innerQuery = queryBuilder.toQuery(context);
   assert innerQuery instanceof SpanQuery;
   return new FieldMaskingSpanQuery((SpanQuery) innerQuery, fieldInQuery);
 }
 @Override
 protected void doAssertLuceneQuery(
     GeoDistanceRangeQueryBuilder queryBuilder, Query query, QueryShardContext context)
     throws IOException {
   Version version = context.indexVersionCreated();
   if (version.before(Version.V_2_2_0)) {
     assertLegacyQuery(queryBuilder, query);
   } else {
     assertGeoPointQuery(queryBuilder, query);
   }
 }
  @Override
  protected Query doToQuery(QueryShardContext context) throws IOException {
    String field;
    MappedFieldType fieldType = context.fieldMapper(fieldName);
    if (fieldType != null) {
      field = fieldType.names().indexName();
    } else {
      field = fieldName;
    }

    Analyzer analyzerObj;
    if (analyzer == null) {
      if (fieldType != null) {
        analyzerObj = context.getSearchAnalyzer(fieldType);
      } else {
        analyzerObj = context.getMapperService().searchAnalyzer();
      }
    } else {
      analyzerObj = context.getMapperService().analysisService().analyzer(analyzer);
      if (analyzerObj == null) {
        throw new QueryShardException(context, "[common] analyzer [" + analyzer + "] not found");
      }
    }

    Occur highFreqOccur = highFreqOperator.toBooleanClauseOccur();
    Occur lowFreqOccur = lowFreqOperator.toBooleanClauseOccur();

    ExtendedCommonTermsQuery commonsQuery =
        new ExtendedCommonTermsQuery(
            highFreqOccur, lowFreqOccur, cutoffFrequency, disableCoord, fieldType);
    return parseQueryString(
        commonsQuery,
        text,
        field,
        analyzerObj,
        lowFreqMinimumShouldMatch,
        highFreqMinimumShouldMatch);
  }
 @Override
 protected void doAssertLuceneQuery(
     GeoBoundingBoxQueryBuilder queryBuilder, Query query, SearchContext searchContext)
     throws IOException {
   QueryShardContext context = searchContext.getQueryShardContext();
   MappedFieldType fieldType = context.fieldMapper(queryBuilder.fieldName());
   if (fieldType == null) {
     assertTrue("Found no indexed geo query.", query instanceof MatchNoDocsQuery);
   } else {
     if (context.indexVersionCreated().before(Version.V_2_2_0)) {
       if (queryBuilder.type() == GeoExecType.INDEXED) {
         assertTrue("Found no indexed geo query.", query instanceof ConstantScoreQuery);
       } else {
         assertTrue(
             "Found no indexed geo query.", query instanceof LegacyInMemoryGeoBoundingBoxQuery);
       }
     } else if (context.indexVersionCreated().before(Version.V_5_0_0_beta1)) {
       assertTrue("Found no indexed geo query.", query instanceof GeoPointInBBoxQuery);
     } else {
       assertTrue("Found no indexed geo query.", query instanceof Query);
     }
   }
 }
    @Override
    protected Query doToQuery(QueryShardContext context) throws IOException {
      MappedFieldType fieldType = context.fieldMapper(fieldName);
      if (fieldType == null) {
        throw new QueryShardException(
            context,
            "failed to parse [{}] query. missing [{}] field [{}]",
            NAME,
            BaseGeoPointFieldMapper.CONTENT_TYPE,
            fieldName);
      }

      if (!(fieldType instanceof BaseGeoPointFieldMapper.GeoPointFieldType)) {
        throw new QueryShardException(
            context,
            "failed to parse [{}] query. field [{}] is not a geo_point field",
            NAME,
            fieldName);
      }

      BaseGeoPointFieldMapper.GeoPointFieldType geoFieldType =
          ((BaseGeoPointFieldMapper.GeoPointFieldType) fieldType);
      if (!geoFieldType.isGeoHashPrefixEnabled()) {
        throw new QueryShardException(
            context,
            "failed to parse [{}] query. [geohash_prefix] is not enabled for field [{}]",
            NAME,
            fieldName);
      }

      String geohash = this.geohash;
      if (levels != null) {
        int len = Math.min(levels, geohash.length());
        geohash = geohash.substring(0, len);
      }

      Query query;
      if (neighbors) {
        query =
            create(
                context,
                geoFieldType,
                geohash,
                GeoHashUtils.addNeighbors(geohash, new ArrayList<CharSequence>(8)));
      } else {
        query = create(context, geoFieldType, geohash, null);
      }
      return query;
    }
  @Override
  protected Query doToQuery(QueryShardContext context) throws IOException {
    Query innerQuery;
    String[] previousTypes = context.getTypes();
    context.setTypes(type);
    try {
      innerQuery = query.toQuery(context);
    } finally {
      context.setTypes(previousTypes);
    }

    DocumentMapper parentDocMapper = context.getMapperService().documentMapper(type);
    if (parentDocMapper == null) {
      if (ignoreUnmapped) {
        return new MatchNoDocsQuery();
      } else {
        throw new QueryShardException(
            context,
            "[" + NAME + "] query configured 'parent_type' [" + type + "] is not a valid type");
      }
    }

    Set<String> childTypes = new HashSet<>();
    ParentChildIndexFieldData parentChildIndexFieldData = null;
    for (DocumentMapper documentMapper : context.getMapperService().docMappers(false)) {
      ParentFieldMapper parentFieldMapper = documentMapper.parentFieldMapper();
      if (parentFieldMapper.active() && type.equals(parentFieldMapper.type())) {
        childTypes.add(documentMapper.type());
        parentChildIndexFieldData = context.getForField(parentFieldMapper.fieldType());
      }
    }

    if (childTypes.isEmpty()) {
      throw new QueryShardException(
          context, "[" + NAME + "] no child types found for type [" + type + "]");
    }

    Query childrenQuery;
    if (childTypes.size() == 1) {
      DocumentMapper documentMapper =
          context.getMapperService().documentMapper(childTypes.iterator().next());
      childrenQuery = documentMapper.typeFilter();
    } else {
      BooleanQuery.Builder childrenFilter = new BooleanQuery.Builder();
      for (String childrenTypeStr : childTypes) {
        DocumentMapper documentMapper = context.getMapperService().documentMapper(childrenTypeStr);
        childrenFilter.add(documentMapper.typeFilter(), BooleanClause.Occur.SHOULD);
      }
      childrenQuery = childrenFilter.build();
    }

    // wrap the query with type query
    innerQuery = Queries.filtered(innerQuery, parentDocMapper.typeFilter());
    return new HasChildQueryBuilder.LateParsingQuery(
        childrenQuery,
        innerQuery,
        HasChildQueryBuilder.DEFAULT_MIN_CHILDREN,
        HasChildQueryBuilder.DEFAULT_MAX_CHILDREN,
        type,
        score ? ScoreMode.Max : ScoreMode.None,
        parentChildIndexFieldData,
        context.getSearchSimilarity());
  }