/**
  * Parse a field as though it were a string.
  *
  * @param context parse context used during parsing
  * @param nullValue value to use for null
  * @param defaultBoost default boost value returned unless overwritten in the field
  * @return the parsed field and the boost either parsed or defaulted
  * @throws IOException if thrown while parsing
  */
 public static ValueAndBoost parseCreateFieldForString(
     ParseContext context, String nullValue, float defaultBoost) throws IOException {
   if (context.externalValueSet()) {
     return new ValueAndBoost(context.externalValue().toString(), defaultBoost);
   }
   XContentParser parser = context.parser();
   if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
     return new ValueAndBoost(nullValue, defaultBoost);
   }
   if (parser.currentToken() == XContentParser.Token.START_OBJECT
       && Version.indexCreated(context.indexSettings()).before(Version.V_3_0_0)) {
     XContentParser.Token token;
     String currentFieldName = null;
     String value = nullValue;
     float boost = defaultBoost;
     while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
       if (token == XContentParser.Token.FIELD_NAME) {
         currentFieldName = parser.currentName();
       } else {
         if ("value".equals(currentFieldName) || "_value".equals(currentFieldName)) {
           value = parser.textOrNull();
         } else if ("boost".equals(currentFieldName) || "_boost".equals(currentFieldName)) {
           boost = parser.floatValue();
         } else {
           throw new IllegalArgumentException("unknown property [" + currentFieldName + "]");
         }
       }
     }
     return new ValueAndBoost(value, boost);
   }
   return new ValueAndBoost(parser.textOrNull(), defaultBoost);
 }
Exemplo n.º 2
0
 public static TermsLookup parseTermsLookup(XContentParser parser) throws IOException {
   String index = null;
   String type = null;
   String id = null;
   String path = null;
   String routing = null;
   XContentParser.Token token;
   String currentFieldName = "";
   while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
     if (token == XContentParser.Token.FIELD_NAME) {
       currentFieldName = parser.currentName();
     } else if (token.isValue()) {
       switch (currentFieldName) {
         case "index":
           index = parser.textOrNull();
           break;
         case "type":
           type = parser.text();
           break;
         case "id":
           id = parser.text();
           break;
         case "routing":
           routing = parser.textOrNull();
           break;
         case "path":
           path = parser.text();
           break;
         default:
           throw new ParsingException(
               parser.getTokenLocation(),
               "["
                   + TermsQueryBuilder.NAME
                   + "] query does not support ["
                   + currentFieldName
                   + "] within lookup element");
       }
     } else {
       throw new ParsingException(
           parser.getTokenLocation(),
           "["
               + TermsQueryBuilder.NAME
               + "] unknown token ["
               + token
               + "] after ["
               + currentFieldName
               + "]");
     }
   }
   return new TermsLookup(index, type, id, path).routing(routing);
 }
 @Override
 protected Field parseCreateField(ParseContext context) throws IOException {
   String value = nullValue;
   float boost = this.boost;
   if (context.externalValueSet()) {
     value = (String) context.externalValue();
   } else {
     XContentParser parser = context.parser();
     if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
       value = nullValue;
     } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
       XContentParser.Token token;
       String currentFieldName = null;
       while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
         if (token == XContentParser.Token.FIELD_NAME) {
           currentFieldName = parser.currentName();
         } else {
           if ("value".equals(currentFieldName) || "_value".equals(currentFieldName)) {
             value = parser.textOrNull();
           } else if ("boost".equals(currentFieldName) || "_boost".equals(currentFieldName)) {
             boost = parser.floatValue();
           } else {
             throw new ElasticSearchIllegalArgumentException(
                 "unknown property [" + currentFieldName + "]");
           }
         }
       }
     } else {
       value = parser.textOrNull();
     }
   }
   if (value == null) {
     return null;
   }
   if (ignoreAbove > 0 && value.length() > ignoreAbove) {
     return null;
   }
   if (context.includeInAll(includeInAll, this)) {
     context.allEntries().addText(names.fullName(), value, boost);
   }
   if (!fieldType().indexed() && !fieldType().stored()) {
     context.ignoredValue(names.indexName(), value);
     return null;
   }
   Field field = new StringField(names.indexName(), value, fieldType);
   field.setBoost(boost);
   return field;
 }
      private void parse(BytesReference data) throws Exception {
        XContent xContent = XContentFactory.xContent(data);
        String source = XContentBuilder.builder(xContent).string();
        int from = 0;
        int length = data.length();
        byte marker = xContent.streamSeparator();
        int nextMarker = findNextMarker(marker, from, data, length);
        if (nextMarker == -1) {
          nextMarker = length;
        }
        // now parse the action
        XContentParser parser = xContent.createParser(data.slice(from, nextMarker - from));

        try {
          // move pointers
          from = nextMarker + 1;

          // Move to START_OBJECT
          XContentParser.Token token = parser.nextToken();
          if (token == null) {
            throw new Exception("Wrong object structure");
          }
          assert token == XContentParser.Token.START_OBJECT;
          // Move to FIELD_NAME, that's the action
          // token = parser.nextToken();
          // assert token == XContentParser.Token.FIELD_NAME;
          // String action = parser.currentName();

          String id = null;
          String routing = null;
          String parent = null;
          String timestamp = null;
          Long ttl = null;
          String opType = null;
          long version = 0;
          VersionType versionType = VersionType.INTERNAL;
          String percolate = null;

          // at this stage, next token can either be END_OBJECT
          // (and use default index and type, with auto generated
          // id)
          // or START_OBJECT which will have another set of
          // parameters

          String currentFieldName = null;
          while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
            if (token == XContentParser.Token.FIELD_NAME) {
              currentFieldName = parser.currentName();
            } else if (token.isValue()) {
              if ("_index".equals(currentFieldName)) {
                index = parser.text();
              } else if ("_type".equals(currentFieldName)) {
                type = parser.text();
              } else if ("_queryString".equals(currentFieldName)) {
                queryString = parser.text();
              } else if ("_id".equals(currentFieldName)) {
                id = parser.text();
              } else if ("_routing".equals(currentFieldName)
                  || "routing".equals(currentFieldName)) {
                routing = parser.text();
              } else if ("_parent".equals(currentFieldName) || "parent".equals(currentFieldName)) {
                parent = parser.text();
              } else if ("_timestamp".equals(currentFieldName)
                  || "timestamp".equals(currentFieldName)) {
                timestamp = parser.text();
              } else if ("_ttl".equals(currentFieldName) || "ttl".equals(currentFieldName)) {
                if (parser.currentToken() == XContentParser.Token.VALUE_STRING) {
                  ttl = TimeValue.parseTimeValue(parser.text(), null).millis();
                } else {
                  ttl = parser.longValue();
                }
              } else if ("op_type".equals(currentFieldName) || "opType".equals(currentFieldName)) {
                opType = parser.text();
              } else if ("_version".equals(currentFieldName)
                  || "version".equals(currentFieldName)) {
                version = parser.longValue();
              } else if ("_version_type".equals(currentFieldName)
                  || "_versionType".equals(currentFieldName)
                  || "version_type".equals(currentFieldName)
                  || "versionType".equals(currentFieldName)) {
                versionType = VersionType.fromString(parser.text());
              } else if ("percolate".equals(currentFieldName)
                  || "_percolate".equals(currentFieldName)) {
                percolate = parser.textOrNull();
              }
            }
          }
          if (nextMarker < length) {
            nextMarker = findNextMarker(marker, from, data, length);
            if (nextMarker == -1) {
              nextMarker = length;
            }
            content = getString(data.slice(from, nextMarker - from));
          }

        } finally {
          parser.close();
        }
      }
  @Override
  public void handleRequest(
      final RestRequest request, final RestChannel channel, final NodeClient client)
      throws Exception {
    String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
    String alias = request.param("name");
    Map<String, Object> filter = null;
    String routing = null;
    String indexRouting = null;
    String searchRouting = null;

    if (request.hasContent()) {
      try (XContentParser parser =
          XContentFactory.xContent(request.content()).createParser(request.content())) {
        XContentParser.Token token = parser.nextToken();
        if (token == null) {
          throw new IllegalArgumentException("No index alias is specified");
        }
        String currentFieldName = null;
        while ((token = parser.nextToken()) != null) {
          if (token == XContentParser.Token.FIELD_NAME) {
            currentFieldName = parser.currentName();
          } else if (token.isValue()) {
            if ("index".equals(currentFieldName)) {
              indices = Strings.splitStringByCommaToArray(parser.text());
            } else if ("alias".equals(currentFieldName)) {
              alias = parser.text();
            } else if ("routing".equals(currentFieldName)) {
              routing = parser.textOrNull();
            } else if ("indexRouting".equals(currentFieldName)
                || "index-routing".equals(currentFieldName)
                || "index_routing".equals(currentFieldName)) {
              indexRouting = parser.textOrNull();
            } else if ("searchRouting".equals(currentFieldName)
                || "search-routing".equals(currentFieldName)
                || "search_routing".equals(currentFieldName)) {
              searchRouting = parser.textOrNull();
            }
          } else if (token == XContentParser.Token.START_OBJECT) {
            if ("filter".equals(currentFieldName)) {
              filter = parser.mapOrdered();
            }
          }
        }
      }
    }

    IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
    indicesAliasesRequest.timeout(request.paramAsTime("timeout", indicesAliasesRequest.timeout()));
    indicesAliasesRequest.masterNodeTimeout(
        request.paramAsTime("master_timeout", indicesAliasesRequest.masterNodeTimeout()));

    IndicesAliasesRequest.AliasActions aliasAction =
        AliasActions.add().indices(indices).alias(alias);
    if (routing != null) {
      aliasAction.routing(routing);
    }
    if (searchRouting != null) {
      aliasAction.searchRouting(searchRouting);
    }
    if (indexRouting != null) {
      aliasAction.indexRouting(indexRouting);
    }
    if (filter != null) {
      aliasAction.filter(filter);
    }
    indicesAliasesRequest.addAliasAction(aliasAction);
    client
        .admin()
        .indices()
        .aliases(indicesAliasesRequest, new AcknowledgedRestListener<>(channel));
  }
  @Override
  public void handleRequest(final RestRequest request, final RestChannel channel) {
    IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
    indicesAliasesRequest.listenerThreaded(false);
    indicesAliasesRequest.masterNodeTimeout(
        request.paramAsTime("master_timeout", indicesAliasesRequest.masterNodeTimeout()));
    XContentParser parser = null;
    try {
      // {
      //     actions : [
      //         { add : { index : "test1", alias : "alias1", filter : {"user" : "kimchy"} } }
      //         { remove : { index : "test1", alias : "alias1" } }
      //     ]
      // }
      indicesAliasesRequest.timeout(
          request.paramAsTime("timeout", indicesAliasesRequest.timeout()));
      parser = XContentFactory.xContent(request.content()).createParser(request.content());
      XContentParser.Token token = parser.nextToken();
      if (token == null) {
        throw new ElasticsearchIllegalArgumentException("No action is specified");
      }
      while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
        if (token == XContentParser.Token.START_ARRAY) {
          while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
            if (token == XContentParser.Token.FIELD_NAME) {
              String action = parser.currentName();
              AliasAction.Type type;
              if ("add".equals(action)) {
                type = AliasAction.Type.ADD;
              } else if ("remove".equals(action)) {
                type = AliasAction.Type.REMOVE;
              } else {
                throw new ElasticsearchIllegalArgumentException(
                    "Alias action [" + action + "] not supported");
              }
              String index = null;
              String alias = null;
              Map<String, Object> filter = null;
              String routing = null;
              boolean routingSet = false;
              String indexRouting = null;
              boolean indexRoutingSet = false;
              String searchRouting = null;
              boolean searchRoutingSet = false;
              String currentFieldName = null;
              while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                  currentFieldName = parser.currentName();
                } else if (token == XContentParser.Token.VALUE_STRING) {
                  if ("index".equals(currentFieldName)) {
                    index = parser.text();
                  } else if ("alias".equals(currentFieldName)) {
                    alias = parser.text();
                  } else if ("routing".equals(currentFieldName)) {
                    routing = parser.textOrNull();
                    routingSet = true;
                  } else if ("indexRouting".equals(currentFieldName)
                      || "index-routing".equals(currentFieldName)
                      || "index_routing".equals(currentFieldName)) {
                    indexRouting = parser.textOrNull();
                    indexRoutingSet = true;
                  } else if ("searchRouting".equals(currentFieldName)
                      || "search-routing".equals(currentFieldName)
                      || "search_routing".equals(currentFieldName)) {
                    searchRouting = parser.textOrNull();
                    searchRoutingSet = true;
                  }
                } else if (token == XContentParser.Token.START_OBJECT) {
                  if ("filter".equals(currentFieldName)) {
                    filter = parser.mapOrdered();
                  }
                }
              }

              if (type == AliasAction.Type.ADD) {
                AliasAction aliasAction = newAddAliasAction(index, alias).filter(filter);
                if (routingSet) {
                  aliasAction.routing(routing);
                }
                if (indexRoutingSet) {
                  aliasAction.indexRouting(indexRouting);
                }
                if (searchRoutingSet) {
                  aliasAction.searchRouting(searchRouting);
                }
                indicesAliasesRequest.addAliasAction(aliasAction);
              } else if (type == AliasAction.Type.REMOVE) {
                indicesAliasesRequest.removeAlias(index, alias);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      try {
        channel.sendResponse(new XContentThrowableRestResponse(request, e));
      } catch (IOException e1) {
        logger.warn("Failed to send response", e1);
      }
      return;
    } finally {
      parser.close();
    }
    client
        .admin()
        .indices()
        .aliases(
            indicesAliasesRequest,
            new AcknowledgedRestResponseActionListener<IndicesAliasesResponse>(
                request, channel, logger));
  }
  @Override
  public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
    XContentParser parser = parseContext.parser();

    XContentParser.Token token;

    boolean cache = false;
    CacheKeyFilter.Key cacheKey = null;
    String filterName = null;
    String currentFieldName = null;
    double lat = 0;
    double lon = 0;
    String fieldName = null;
    Object vFrom = null;
    Object vTo = null;
    boolean includeLower = true;
    boolean includeUpper = true;
    DistanceUnit unit = DistanceUnit.KILOMETERS; // default unit
    GeoDistance geoDistance = GeoDistance.ARC;
    String optimizeBbox = "memory";
    boolean normalizeLon = true;
    boolean normalizeLat = true;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.START_ARRAY) {
        token = parser.nextToken();
        lon = parser.doubleValue();
        token = parser.nextToken();
        lat = parser.doubleValue();
        while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {}

        fieldName = currentFieldName;
      } else if (token == XContentParser.Token.START_OBJECT) {
        // the json in the format of -> field : { lat : 30, lon : 12 }
        String currentName = parser.currentName();
        fieldName = currentFieldName;
        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
          if (token == XContentParser.Token.FIELD_NAME) {
            currentName = parser.currentName();
          } else if (token.isValue()) {
            if (currentName.equals(GeoPointFieldMapper.Names.LAT)) {
              lat = parser.doubleValue();
            } else if (currentName.equals(GeoPointFieldMapper.Names.LON)) {
              lon = parser.doubleValue();
            } else if (currentName.equals(GeoPointFieldMapper.Names.GEOHASH)) {
              double[] values = GeoHashUtils.decode(parser.text());
              lat = values[0];
              lon = values[1];
            }
          }
        }
      } else if (token.isValue()) {
        if (currentFieldName.equals("from")) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vFrom = parser.text(); // a String
          } else {
            vFrom = parser.numberValue(); // a Number
          }
        } else if (currentFieldName.equals("to")) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vTo = parser.text(); // a String
          } else {
            vTo = parser.numberValue(); // a Number
          }
        } else if ("include_lower".equals(currentFieldName)
            || "includeLower".equals(currentFieldName)) {
          includeLower = parser.booleanValue();
        } else if ("include_upper".equals(currentFieldName)
            || "includeUpper".equals(currentFieldName)) {
          includeUpper = parser.booleanValue();
        } else if ("gt".equals(currentFieldName)) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vFrom = parser.text(); // a String
          } else {
            vFrom = parser.numberValue(); // a Number
          }
          includeLower = false;
        } else if ("gte".equals(currentFieldName) || "ge".equals(currentFieldName)) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vFrom = parser.text(); // a String
          } else {
            vFrom = parser.numberValue(); // a Number
          }
          includeLower = true;
        } else if ("lt".equals(currentFieldName)) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vTo = parser.text(); // a String
          } else {
            vTo = parser.numberValue(); // a Number
          }
          includeUpper = false;
        } else if ("lte".equals(currentFieldName) || "le".equals(currentFieldName)) {
          if (token == XContentParser.Token.VALUE_NULL) {
          } else if (token == XContentParser.Token.VALUE_STRING) {
            vTo = parser.text(); // a String
          } else {
            vTo = parser.numberValue(); // a Number
          }
          includeUpper = true;
        } else if (currentFieldName.equals("unit")) {
          unit = DistanceUnit.fromString(parser.text());
        } else if (currentFieldName.equals("distance_type")
            || currentFieldName.equals("distanceType")) {
          geoDistance = GeoDistance.fromString(parser.text());
        } else if (currentFieldName.endsWith(GeoPointFieldMapper.Names.LAT_SUFFIX)) {
          lat = parser.doubleValue();
          fieldName =
              currentFieldName.substring(
                  0, currentFieldName.length() - GeoPointFieldMapper.Names.LAT_SUFFIX.length());
        } else if (currentFieldName.endsWith(GeoPointFieldMapper.Names.LON_SUFFIX)) {
          lon = parser.doubleValue();
          fieldName =
              currentFieldName.substring(
                  0, currentFieldName.length() - GeoPointFieldMapper.Names.LON_SUFFIX.length());
        } else if (currentFieldName.endsWith(GeoPointFieldMapper.Names.GEOHASH_SUFFIX)) {
          double[] values = GeoHashUtils.decode(parser.text());
          lat = values[0];
          lon = values[1];
          fieldName =
              currentFieldName.substring(
                  0, currentFieldName.length() - GeoPointFieldMapper.Names.GEOHASH_SUFFIX.length());
        } else if ("_name".equals(currentFieldName)) {
          filterName = parser.text();
        } else if ("_cache".equals(currentFieldName)) {
          cache = parser.booleanValue();
        } else if ("_cache_key".equals(currentFieldName) || "_cacheKey".equals(currentFieldName)) {
          cacheKey = new CacheKeyFilter.Key(parser.text());
        } else if ("optimize_bbox".equals(currentFieldName)
            || "optimizeBbox".equals(currentFieldName)) {
          optimizeBbox = parser.textOrNull();
        } else if ("normalize".equals(currentFieldName)) {
          normalizeLat = parser.booleanValue();
          normalizeLon = parser.booleanValue();
        } else {
          // assume the value is the actual value
          String value = parser.text();
          int comma = value.indexOf(',');
          if (comma != -1) {
            lat = Double.parseDouble(value.substring(0, comma).trim());
            lon = Double.parseDouble(value.substring(comma + 1).trim());
          } else {
            double[] values = GeoHashUtils.decode(value);
            lat = values[0];
            lon = values[1];
          }
          fieldName = currentFieldName;
        }
      }
    }

    Double from = null;
    Double to = null;
    if (vFrom != null) {
      if (vFrom instanceof Number) {
        from = unit.toMiles(((Number) vFrom).doubleValue());
      } else {
        from = DistanceUnit.parse((String) vFrom, unit, DistanceUnit.MILES);
      }
      from = geoDistance.normalize(from, DistanceUnit.MILES);
    }
    if (vTo != null) {
      if (vTo instanceof Number) {
        to = unit.toMiles(((Number) vTo).doubleValue());
      } else {
        to = DistanceUnit.parse((String) vTo, unit, DistanceUnit.MILES);
      }
      to = geoDistance.normalize(to, DistanceUnit.MILES);
    }

    if (normalizeLat) {
      lat = GeoUtils.normalizeLat(lat);
    }
    if (normalizeLon) {
      lon = GeoUtils.normalizeLon(lon);
    }

    MapperService.SmartNameFieldMappers smartMappers = parseContext.smartFieldMappers(fieldName);
    if (smartMappers == null || !smartMappers.hasMapper()) {
      throw new QueryParsingException(
          parseContext.index(), "failed to find geo_point field [" + fieldName + "]");
    }
    FieldMapper mapper = smartMappers.mapper();
    if (mapper.fieldDataType() != GeoPointFieldDataType.TYPE) {
      throw new QueryParsingException(
          parseContext.index(), "field [" + fieldName + "] is not a geo_point field");
    }
    GeoPointFieldMapper geoMapper = ((GeoPointFieldMapper.GeoStringFieldMapper) mapper).geoMapper();
    fieldName = mapper.names().indexName();

    Filter filter =
        new GeoDistanceRangeFilter(
            lat,
            lon,
            from,
            to,
            includeLower,
            includeUpper,
            geoDistance,
            fieldName,
            geoMapper,
            parseContext.indexCache().fieldData(),
            optimizeBbox);
    if (cache) {
      filter = parseContext.cacheFilter(filter, cacheKey);
    }
    filter = wrapSmartNameFilter(filter, smartMappers, parseContext);
    if (filterName != null) {
      parseContext.addNamedFilter(filterName, filter);
    }
    return filter;
  }
 private void addCompoundSortField(
     XContentParser parser, SearchContext context, List<SortField> sortFields) throws Exception {
   XContentParser.Token token;
   while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
     if (token == XContentParser.Token.FIELD_NAME) {
       String fieldName = parser.currentName();
       boolean reverse = false;
       String missing = null;
       String innerJsonName = null;
       boolean ignoreUnmapped = false;
       SortMode sortMode = null;
       Filter nestedFilter = null;
       String nestedPath = null;
       token = parser.nextToken();
       if (token == XContentParser.Token.VALUE_STRING) {
         String direction = parser.text();
         if (direction.equals("asc")) {
           reverse = SCORE_FIELD_NAME.equals(fieldName);
         } else if (direction.equals("desc")) {
           reverse = !SCORE_FIELD_NAME.equals(fieldName);
         } else {
           throw new ElasticSearchIllegalArgumentException(
               "sort direction [" + fieldName + "] not supported");
         }
         addSortField(
             context,
             sortFields,
             fieldName,
             reverse,
             ignoreUnmapped,
             missing,
             sortMode,
             nestedPath,
             nestedFilter);
       } else {
         if (parsers.containsKey(fieldName)) {
           sortFields.add(parsers.get(fieldName).parse(parser, context));
         } else {
           while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
             if (token == XContentParser.Token.FIELD_NAME) {
               innerJsonName = parser.currentName();
             } else if (token.isValue()) {
               if ("reverse".equals(innerJsonName)) {
                 reverse = parser.booleanValue();
               } else if ("order".equals(innerJsonName)) {
                 if ("asc".equals(parser.text())) {
                   reverse = SCORE_FIELD_NAME.equals(fieldName);
                 } else if ("desc".equals(parser.text())) {
                   reverse = !SCORE_FIELD_NAME.equals(fieldName);
                 }
               } else if ("missing".equals(innerJsonName)) {
                 missing = parser.textOrNull();
               } else if ("ignore_unmapped".equals(innerJsonName)
                   || "ignoreUnmapped".equals(innerJsonName)) {
                 ignoreUnmapped = parser.booleanValue();
               } else if ("sort_mode".equals(innerJsonName)
                   || "sortMode".equals(innerJsonName)
                   || "mode".equals(innerJsonName)) {
                 sortMode = SortMode.fromString(parser.text());
               } else if ("nested_path".equals(innerJsonName)
                   || "nestedPath".equals(innerJsonName)) {
                 nestedPath = parser.text();
               } else {
                 throw new ElasticSearchIllegalArgumentException(
                     "sort option [" + innerJsonName + "] not supported");
               }
             } else if (token == XContentParser.Token.START_OBJECT) {
               if ("nested_filter".equals(innerJsonName) || "nestedFilter".equals(innerJsonName)) {
                 nestedFilter = context.queryParserService().parseInnerFilter(parser);
               } else {
                 throw new ElasticSearchIllegalArgumentException(
                     "sort option [" + innerJsonName + "] not supported");
               }
             }
           }
           addSortField(
               context,
               sortFields,
               fieldName,
               reverse,
               ignoreUnmapped,
               missing,
               sortMode,
               nestedPath,
               nestedFilter);
         }
       }
     }
   }
 }
Exemplo n.º 9
0
  @Override
  public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
    XContentParser parser = parseContext.parser();

    Query query = null;
    Query noMatchQuery = Queries.newMatchAllQuery();
    boolean queryFound = false;
    boolean indicesFound = false;
    boolean currentIndexMatchesIndices = false;
    String queryName = null;

    String currentFieldName = null;
    XContentParser.Token token;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.START_OBJECT) {
        if ("query".equals(currentFieldName)) {
          // TODO We are able to decide whether to parse the query or not only if indices in the
          // query appears first
          queryFound = true;
          if (indicesFound && !currentIndexMatchesIndices) {
            parseContext.parser().skipChildren(); // skip the query object without parsing it
          } else {
            query = parseContext.parseInnerQuery();
          }
        } else if ("no_match_query".equals(currentFieldName)) {
          if (indicesFound && currentIndexMatchesIndices) {
            parseContext.parser().skipChildren(); // skip the query object without parsing it
          } else {
            noMatchQuery = parseContext.parseInnerQuery();
          }
        } else {
          throw new QueryParsingException(
              parseContext.index(), "[indices] query does not support [" + currentFieldName + "]");
        }
      } else if (token == XContentParser.Token.START_ARRAY) {
        if ("indices".equals(currentFieldName)) {
          if (indicesFound) {
            throw new QueryParsingException(
                parseContext.index(), "[indices] indices or index already specified");
          }
          indicesFound = true;
          Collection<String> indices = new ArrayList<>();
          while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
            String value = parser.textOrNull();
            if (value == null) {
              throw new QueryParsingException(
                  parseContext.index(), "[indices] no value specified for 'indices' entry");
            }
            indices.add(value);
          }
          currentIndexMatchesIndices =
              matchesIndices(
                  parseContext.index().name(), indices.toArray(new String[indices.size()]));
        } else {
          throw new QueryParsingException(
              parseContext.index(), "[indices] query does not support [" + currentFieldName + "]");
        }
      } else if (token.isValue()) {
        if ("index".equals(currentFieldName)) {
          if (indicesFound) {
            throw new QueryParsingException(
                parseContext.index(), "[indices] indices or index already specified");
          }
          indicesFound = true;
          currentIndexMatchesIndices = matchesIndices(parseContext.index().name(), parser.text());
        } else if ("no_match_query".equals(currentFieldName)) {
          String type = parser.text();
          if ("all".equals(type)) {
            noMatchQuery = Queries.newMatchAllQuery();
          } else if ("none".equals(type)) {
            noMatchQuery = Queries.newMatchNoDocsQuery();
          }
        } else if ("_name".equals(currentFieldName)) {
          queryName = parser.text();
        } else {
          throw new QueryParsingException(
              parseContext.index(), "[indices] query does not support [" + currentFieldName + "]");
        }
      }
    }
    if (!queryFound) {
      throw new QueryParsingException(parseContext.index(), "[indices] requires 'query' element");
    }
    if (!indicesFound) {
      throw new QueryParsingException(
          parseContext.index(), "[indices] requires 'indices' or 'index' element");
    }

    Query chosenQuery;
    if (currentIndexMatchesIndices) {
      chosenQuery = query;
    } else {
      chosenQuery = noMatchQuery;
    }
    if (queryName != null) {
      parseContext.addNamedQuery(queryName, chosenQuery);
    }
    return chosenQuery;
  }
Exemplo n.º 10
0
  @Override
  public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
    XContentParser parser = parseContext.parser();

    String fieldName = null;
    boolean disableCoord = false;
    float boost = 1.0f;
    String minimumShouldMatch = null;
    List<String> values = newArrayList();

    String currentFieldName = null;
    XContentParser.Token token;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.START_ARRAY) {
        fieldName = currentFieldName;
        while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
          String value = parser.text();
          if (value == null) {
            throw new QueryParsingException(
                parseContext.index(), "No value specified for terms query");
          }
          values.add(value);
        }
      } else if (token.isValue()) {
        if ("disable_coord".equals(currentFieldName) || "disableCoord".equals(currentFieldName)) {
          disableCoord = parser.booleanValue();
        } else if ("minimum_match".equals(currentFieldName)
            || "minimumMatch".equals(currentFieldName)) {
          minimumShouldMatch = parser.textOrNull();
        } else if ("minimum_should_match".equals(currentFieldName)
            || "minimumShouldMatch".equals(currentFieldName)) {
          minimumShouldMatch = parser.textOrNull();
        } else if ("boost".equals(currentFieldName)) {
          boost = parser.floatValue();
        }
      } else {
        throw new QueryParsingException(
            parseContext.index(), "[terms] query does not support [" + currentFieldName + "]");
      }
    }

    FieldMapper mapper = null;
    MapperService.SmartNameFieldMappers smartNameFieldMappers =
        parseContext.smartFieldMappers(fieldName);
    String[] previousTypes = null;
    if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
      mapper = smartNameFieldMappers.mapper();
      if (smartNameFieldMappers.explicitTypeInNameWithDocMapper()) {
        previousTypes =
            QueryParseContext.setTypesWithPrevious(
                new String[] {smartNameFieldMappers.docMapper().type()});
      }
    }

    try {
      BooleanQuery query = new BooleanQuery(disableCoord);
      for (String value : values) {
        if (mapper != null) {
          query.add(
              new BooleanClause(mapper.termQuery(value, parseContext), BooleanClause.Occur.SHOULD));
        } else {
          query.add(new TermQuery(new Term(fieldName, value)), BooleanClause.Occur.SHOULD);
        }
      }
      query.setBoost(boost);
      Queries.applyMinimumShouldMatch(query, minimumShouldMatch);
      return wrapSmartNameQuery(
          optimizeQuery(fixNegativeQueryIfNeeded(query)), smartNameFieldMappers, parseContext);
    } finally {
      if (smartNameFieldMappers != null
          && smartNameFieldMappers.explicitTypeInNameWithDocMapper()) {
        QueryParseContext.setTypes(previousTypes);
      }
    }
  }
Exemplo n.º 11
0
  @Override
  public FacetExecutor parse(String facetName, XContentParser parser, SearchContext context)
      throws IOException {
    String field = null;
    int size = 10;
    int shardSize = -1;

    String[] fieldsNames = null;
    ImmutableSet<BytesRef> excluded = ImmutableSet.of();
    String regex = null;
    String regexFlags = null;
    TermsFacet.ComparatorType comparatorType = TermsFacet.ComparatorType.COUNT;
    String scriptLang = null;
    String script = null;
    ScriptService.ScriptType scriptType = null;
    Map<String, Object> params = null;
    boolean allTerms = false;
    String executionHint = null;

    String currentFieldName = null;
    XContentParser.Token token;
    while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.START_OBJECT) {
        if ("params".equals(currentFieldName)) {
          params = parser.map();
        } else {
          throw new ElasticsearchParseException(
              "unknown parameter ["
                  + currentFieldName
                  + "] while parsing terms facet ["
                  + facetName
                  + "]");
        }
      } else if (token == XContentParser.Token.START_ARRAY) {
        if ("exclude".equals(currentFieldName)) {
          ImmutableSet.Builder<BytesRef> builder = ImmutableSet.builder();
          while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
            builder.add(parser.bytes());
          }
          excluded = builder.build();
        } else if ("fields".equals(currentFieldName)) {
          List<String> fields = Lists.newArrayListWithCapacity(4);
          while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
            fields.add(parser.text());
          }
          fieldsNames = fields.toArray(new String[fields.size()]);
        } else {
          throw new ElasticsearchParseException(
              "unknown parameter ["
                  + currentFieldName
                  + "] while parsing terms facet ["
                  + facetName
                  + "]");
        }
      } else if (token.isValue()) {
        if ("field".equals(currentFieldName)) {
          field = parser.text();
        } else if (ScriptService.SCRIPT_INLINE.match(currentFieldName)) {
          script = parser.text();
          scriptType = ScriptService.ScriptType.INLINE;
        } else if (ScriptService.SCRIPT_ID.match(currentFieldName)) {
          script = parser.text();
          scriptType = ScriptService.ScriptType.INDEXED;
        } else if (ScriptService.SCRIPT_FILE.match(currentFieldName)) {
          script = parser.text();
          scriptType = ScriptService.ScriptType.FILE;
        } else if (ScriptService.SCRIPT_LANG.match(currentFieldName)) {
          scriptLang = parser.text();
        } else if ("size".equals(currentFieldName)) {
          size = parser.intValue();
        } else if ("shard_size".equals(currentFieldName) || "shardSize".equals(currentFieldName)) {
          shardSize = parser.intValue();
        } else if ("all_terms".equals(currentFieldName) || "allTerms".equals(currentFieldName)) {
          allTerms = parser.booleanValue();
        } else if ("regex".equals(currentFieldName)) {
          regex = parser.text();
        } else if ("regex_flags".equals(currentFieldName)
            || "regexFlags".equals(currentFieldName)) {
          regexFlags = parser.text();
        } else if ("order".equals(currentFieldName) || "comparator".equals(currentFieldName)) {
          comparatorType = TermsFacet.ComparatorType.fromString(parser.text());
        } else if ("execution_hint".equals(currentFieldName)
            || "executionHint".equals(currentFieldName)) {
          executionHint = parser.textOrNull();
        } else {
          throw new ElasticsearchParseException(
              "unknown parameter ["
                  + currentFieldName
                  + "] while parsing terms facet ["
                  + facetName
                  + "]");
        }
      }
    }

    if (fieldsNames != null && fieldsNames.length == 1) {
      field = fieldsNames[0];
      fieldsNames = null;
    }

    Pattern pattern = null;
    if (regex != null) {
      pattern = Regex.compile(regex, regexFlags);
    }

    SearchScript searchScript = null;
    if (script != null) {
      searchScript =
          context.scriptService().search(context.lookup(), scriptLang, script, scriptType, params);
    }

    // shard_size cannot be smaller than size as we need to at least fetch <size> entries from every
    // shards in order to return <size>
    if (shardSize < size) {
      shardSize = size;
    }

    if (fieldsNames != null) {

      // in case of multi files, we only collect the fields that are mapped and facet on them.
      ArrayList<FieldMapper> mappers = new ArrayList<>(fieldsNames.length);
      for (int i = 0; i < fieldsNames.length; i++) {
        FieldMapper mapper = context.smartNameFieldMapper(fieldsNames[i]);
        if (mapper != null) {
          mappers.add(mapper);
        }
      }
      if (mappers.isEmpty()) {
        // non of the fields is mapped
        return new UnmappedFieldExecutor(size, comparatorType);
      }
      return new FieldsTermsStringFacetExecutor(
          mappers.toArray(new FieldMapper[mappers.size()]),
          size,
          shardSize,
          comparatorType,
          allTerms,
          context,
          excluded,
          pattern,
          searchScript);
    }
    if (field == null && script != null) {
      return new ScriptTermsStringFieldFacetExecutor(
          size,
          shardSize,
          comparatorType,
          context,
          excluded,
          pattern,
          scriptLang,
          script,
          scriptType,
          params,
          context.cacheRecycler());
    }

    if (field == null) {
      throw new ElasticsearchParseException(
          "terms facet [" + facetName + "] must have a field, fields or script parameter");
    }

    FieldMapper fieldMapper = context.smartNameFieldMapper(field);
    if (fieldMapper == null) {
      return new UnmappedFieldExecutor(size, comparatorType);
    }

    IndexFieldData indexFieldData = context.fieldData().getForField(fieldMapper);
    if (indexFieldData instanceof IndexNumericFieldData) {
      IndexNumericFieldData indexNumericFieldData = (IndexNumericFieldData) indexFieldData;
      if (indexNumericFieldData.getNumericType().isFloatingPoint()) {
        return new TermsDoubleFacetExecutor(
            indexNumericFieldData,
            size,
            shardSize,
            comparatorType,
            allTerms,
            context,
            excluded,
            searchScript,
            context.cacheRecycler());
      } else {
        return new TermsLongFacetExecutor(
            indexNumericFieldData,
            size,
            shardSize,
            comparatorType,
            allTerms,
            context,
            excluded,
            searchScript,
            context.cacheRecycler());
      }
    } else {
      if (script != null || "map".equals(executionHint)) {
        return new TermsStringFacetExecutor(
            indexFieldData,
            size,
            shardSize,
            comparatorType,
            allTerms,
            context,
            excluded,
            pattern,
            searchScript);
      } else if (indexFieldData instanceof IndexOrdinalsFieldData) {
        return new TermsStringOrdinalsFacetExecutor(
            (IndexOrdinalsFieldData) indexFieldData,
            size,
            shardSize,
            comparatorType,
            allTerms,
            context,
            excluded,
            pattern,
            ordinalsCacheAbove);
      } else {
        return new TermsStringFacetExecutor(
            indexFieldData,
            size,
            shardSize,
            comparatorType,
            allTerms,
            context,
            excluded,
            pattern,
            searchScript);
      }
    }
  }