@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;
    }
  /**
   * Create a new geohash filter for a given set of geohashes. In general this method returns a
   * boolean filter combining the geohashes OR-wise.
   *
   * @param context Context of the filter
   * @param fieldType field mapper for geopoints
   * @param geohash mandatory geohash
   * @param geohashes optional array of additional geohashes
   * @return a new GeoBoundinboxfilter
   */
  public static Query create(
      QueryShardContext context,
      BaseGeoPointFieldMapper.GeoPointFieldType fieldType,
      String geohash,
      @Nullable List<CharSequence> geohashes) {
    MappedFieldType geoHashMapper = fieldType.geoHashFieldType();
    if (geoHashMapper == null) {
      throw new IllegalArgumentException("geohash filter needs geohash_prefix to be enabled");
    }

    if (geohashes == null || geohashes.size() == 0) {
      return geoHashMapper.termQuery(geohash, context);
    } else {
      geohashes.add(geohash);
      return geoHashMapper.termsQuery(geohashes, context);
    }
  }