public static Filter newFilter( QueryParseContext parseContext, String fieldPattern, String filterName) { final FieldMappers fieldNamesMappers = parseContext.mapperService().indexName(FieldNamesFieldMapper.NAME); final FieldNamesFieldMapper fieldNamesMapper = fieldNamesMappers == null ? null : (FieldNamesFieldMapper) fieldNamesMappers.mapper(); MapperService.SmartNameObjectMapper smartNameObjectMapper = parseContext.smartObjectMapper(fieldPattern); if (smartNameObjectMapper != null && smartNameObjectMapper.hasMapper()) { // automatic make the object mapper pattern fieldPattern = fieldPattern + ".*"; } List<String> fields = parseContext.simpleMatchToIndexNames(fieldPattern); if (fields.isEmpty()) { // no fields exists, so we should not match anything return Queries.MATCH_NO_FILTER; } MapperService.SmartNameFieldMappers nonNullFieldMappers = null; XBooleanFilter boolFilter = new XBooleanFilter(); for (String field : fields) { MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(field); if (smartNameFieldMappers != null) { nonNullFieldMappers = smartNameFieldMappers; } Filter filter = null; if (fieldNamesMapper != null && fieldNamesMapper.enabled()) { final String f; if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { f = smartNameFieldMappers.mapper().names().indexName(); } else { f = field; } filter = fieldNamesMapper.termFilter(f, parseContext); } // if _field_names are not indexed, we need to go the slow way if (filter == null && smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext); } if (filter == null) { filter = new TermRangeFilter(field, null, null, true, true); } boolFilter.add(filter, BooleanClause.Occur.SHOULD); } // we always cache this one, really does not change... (exists) // its ok to cache under the fieldName cacheKey, since its per segment and the mapping applies // to this data on this segment... Filter filter = parseContext.cacheFilter(boolFilter, new CacheKeyFilter.Key("$exists$" + fieldPattern)); filter = wrapSmartNameFilter(filter, nonNullFieldMappers, parseContext); if (filterName != null) { parseContext.addNamedFilter(filterName, filter); } return filter; }
public TermsLongOrdinalsFacetCollector( String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context, ImmutableSet<String> excluded) { super(facetName); this.fieldDataCache = context.fieldDataCache(); this.size = size; this.comparatorType = comparatorType; this.numberOfShards = context.numberOfShards(); MapperService.SmartNameFieldMappers smartMappers = context.mapperService().smartName(fieldName); if (smartMappers == null || !smartMappers.hasMapper()) { throw new ElasticSearchIllegalArgumentException( "Field [" + fieldName + "] doesn't have a type, can't run terms long facet collector on it"); } else { // add type filter if there is exact doc mapper associated with it if (smartMappers.hasDocMapper()) { setFilter(context.filterCache().cache(smartMappers.docMapper().typeFilter())); } if (smartMappers.mapper().fieldDataType() != FieldDataType.DefaultTypes.LONG) { throw new ElasticSearchIllegalArgumentException( "Field [" + fieldName + "] is not of long type, can't run terms long facet collector on it"); } this.indexFieldName = smartMappers.mapper().names().indexName(); this.fieldDataType = smartMappers.mapper().fieldDataType(); } if (excluded == null || excluded.isEmpty()) { this.excluded = null; } else { this.excluded = new TLongHashSet(excluded.size()); for (String s : excluded) { this.excluded.add(Long.parseLong(s)); } } // minCount is offset by -1 if (allTerms) { minCount = -1; } else { minCount = 0; } this.aggregators = new ArrayList<ReaderAggregator>(context.searcher().subReaders().length); }
@Override public Filter parse(JsonQueryParseContext parseContext) throws IOException, QueryParsingException { JsonParser jp = parseContext.jp(); JsonToken token = jp.nextToken(); assert token == JsonToken.FIELD_NAME; String fieldName = jp.getCurrentName(); jp.nextToken(); String value = jp.getText(); // move to the next token (from VALUE) jp.nextToken(); if (value == null) { throw new QueryParsingException(index, "No value specified for term filter"); } Filter filter = null; MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers != null) { if (smartNameFieldMappers.hasMapper()) { filter = smartNameFieldMappers.mapper().fieldFilter(value); } } if (filter == null) { filter = new TermFilter(new Term(fieldName, value)); } filter = parseContext.cacheFilterIfPossible(filter); return wrapSmartNameFilter(filter, smartNameFieldMappers, parseContext.indexCache()); }
public ValueGeoDistanceFacetCollector( String facetName, String fieldName, double lat, double lon, DistanceUnit unit, GeoDistance geoDistance, GeoDistanceFacet.Entry[] entries, SearchContext context, String valueFieldName) { super(facetName, fieldName, lat, lon, unit, geoDistance, entries, context); MapperService.SmartNameFieldMappers smartMappers = context.smartFieldMappers(valueFieldName); if (smartMappers == null || !smartMappers.hasMapper()) { throw new FacetPhaseExecutionException( facetName, "No mapping found for field [" + valueFieldName + "]"); } this.indexValueFieldName = smartMappers.mapper().names().indexName(); this.valueFieldDataType = smartMappers.mapper().fieldDataType(); this.aggregator = new Aggregator(fixedSourceDistance, entries); }
private static GeoPointFieldMapper getGeoPointFieldMapper( String fieldName, MapperService mapperService) { MapperService.SmartNameFieldMappers smartMappers = mapperService.smartName(fieldName); if (smartMappers == null || !smartMappers.hasMapper()) { throw new IllegalArgumentException(String.format("column \"%s\" doesn't exist", fieldName)); } FieldMapper mapper = smartMappers.mapper(); if (!(mapper instanceof GeoPointFieldMapper)) { throw new IllegalArgumentException( String.format("column \"%s\" isn't of type geo_point", fieldName)); } return (GeoPointFieldMapper) mapper; }
@Override public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); String fieldName = null; String filterName = null; boolean nullValue = false; boolean existence = true; 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 (token.isValue()) { if ("field".equals(currentFieldName)) { fieldName = parser.text(); } else if ("null_value".equals(currentFieldName)) { nullValue = parser.booleanValue(); } else if ("existence".equals(currentFieldName)) { existence = parser.booleanValue(); } else if ("_name".equals(currentFieldName)) { filterName = parser.text(); } else { throw new QueryParsingException( parseContext.index(), "[missing] filter does not support [" + currentFieldName + "]"); } } } if (fieldName == null) { throw new QueryParsingException( parseContext.index(), "missing must be provided with a [field]"); } if (!existence && !nullValue) { throw new QueryParsingException( parseContext.index(), "missing must have either existence, or null_value, or both set to true"); } Filter existenceFilter = null; Filter nullFilter = null; MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (existence) { if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { existenceFilter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext); } if (existenceFilter == null) { existenceFilter = new TermRangeFilter(fieldName, null, null, true, true); } // we always cache this one, really does not change... (exists) existenceFilter = parseContext.cacheFilter(existenceFilter, null); existenceFilter = new NotFilter(existenceFilter); // cache the not filter as well, so it will be faster existenceFilter = parseContext.cacheFilter(existenceFilter, null); } if (nullValue) { if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { nullFilter = smartNameFieldMappers.mapper().nullValueFilter(); if (nullFilter != null) { // cache the not filter as well, so it will be faster nullFilter = parseContext.cacheFilter(nullFilter, null); } } } Filter filter; if (nullFilter != null) { if (existenceFilter != null) { XBooleanFilter combined = new XBooleanFilter(); combined.addShould(existenceFilter); combined.addShould(nullFilter); // cache the not filter as well, so it will be faster filter = parseContext.cacheFilter(combined, null); } else { filter = nullFilter; } } else { filter = existenceFilter; } if (filter == null) { return null; } filter = wrapSmartNameFilter(filter, smartNameFieldMappers, parseContext); if (filterName != null) { parseContext.addNamedFilter(filterName, existenceFilter); } return filter; }
@Override public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); XContentParser.Token token = parser.nextToken(); if (token != XContentParser.Token.FIELD_NAME) { throw new QueryParsingException( parseContext.index(), "[range] query malformed, no field to indicate field name"); } String fieldName = parser.currentName(); token = parser.nextToken(); if (token != XContentParser.Token.START_OBJECT) { throw new QueryParsingException( parseContext.index(), "[range] query malformed, after field missing start object"); } BytesRef from = null; BytesRef to = null; boolean includeLower = true; boolean includeUpper = true; float boost = 1.0f; String currentFieldName = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else { if ("from".equals(currentFieldName)) { from = parser.bytesOrNull(); } else if ("to".equals(currentFieldName)) { to = parser.bytesOrNull(); } 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 ("boost".equals(currentFieldName)) { boost = parser.floatValue(); } else if ("gt".equals(currentFieldName)) { from = parser.bytesOrNull(); includeLower = false; } else if ("gte".equals(currentFieldName) || "ge".equals(currentFieldName)) { from = parser.bytesOrNull(); includeLower = true; } else if ("lt".equals(currentFieldName)) { to = parser.bytesOrNull(); includeUpper = false; } else if ("lte".equals(currentFieldName) || "le".equals(currentFieldName)) { to = parser.bytesOrNull(); includeUpper = true; } else { throw new QueryParsingException( parseContext.index(), "[range] query does not support [" + currentFieldName + "]"); } } } // move to the next end object, to close the field name token = parser.nextToken(); if (token != XContentParser.Token.END_OBJECT) { throw new QueryParsingException( parseContext.index(), "[range] query malformed, does not end with an object"); } Query query = null; MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers != null) { if (smartNameFieldMappers.hasMapper()) { // LUCENE 4 UPGRADE Mapper#rangeQuery should use bytesref as well? query = smartNameFieldMappers .mapper() .rangeQuery( from != null ? from.utf8ToString() : null, to != null ? to.utf8ToString() : null, includeLower, includeUpper, parseContext); } } if (query == null) { query = new TermRangeQuery(fieldName, from, to, includeLower, includeUpper); } query.setBoost(boost); return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext); }
public TermsShortFacetCollector( String facetName, String fieldName, int size, TermsFacet.ComparatorType comparatorType, boolean allTerms, SearchContext context, String scriptLang, String script, Map<String, Object> params) { super(facetName); this.fieldDataCache = context.fieldDataCache(); this.size = size; this.comparatorType = comparatorType; this.numberOfShards = context.numberOfShards(); MapperService.SmartNameFieldMappers smartMappers = context.mapperService().smartName(fieldName); if (smartMappers == null || !smartMappers.hasMapper()) { throw new ElasticSearchIllegalArgumentException( "Field [" + fieldName + "] doesn't have a type, can't run terms short facet collector on it"); } else { // add type filter if there is exact doc mapper associated with it if (smartMappers.hasDocMapper()) { setFilter(context.filterCache().cache(smartMappers.docMapper().typeFilter())); } if (smartMappers.mapper().fieldDataType() != FieldDataType.DefaultTypes.SHORT) { throw new ElasticSearchIllegalArgumentException( "Field [" + fieldName + "] is not of short type, can't run terms short facet collector on it"); } this.indexFieldName = smartMappers.mapper().names().indexName(); this.fieldDataType = smartMappers.mapper().fieldDataType(); } if (script != null) { this.script = new SearchScript(context.lookup(), scriptLang, script, params, context.scriptService()); } else { this.script = null; } if (this.script == null) { aggregator = new StaticAggregatorValueProc(popFacets()); } else { aggregator = new AggregatorValueProc(popFacets(), this.script); } if (allTerms) { try { for (IndexReader reader : context.searcher().subReaders()) { ShortFieldData fieldData = (ShortFieldData) fieldDataCache.cache(fieldDataType, reader, indexFieldName); fieldData.forEachValue(aggregator); } } catch (Exception e) { throw new FacetPhaseExecutionException(facetName, "failed to load all terms", e); } } }
@Override public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); boolean cache = true; CacheKeyFilter.Key cacheKey = null; String fieldName = null; Object from = null; Object to = null; boolean includeLower = true; boolean includeUpper = true; String filterName = 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) { fieldName = currentFieldName; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else { if ("from".equals(currentFieldName)) { from = parser.objectBytes(); } else if ("to".equals(currentFieldName)) { to = parser.objectBytes(); } 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)) { from = parser.objectBytes(); includeLower = false; } else if ("gte".equals(currentFieldName) || "ge".equals(currentFieldName)) { from = parser.objectBytes(); includeLower = true; } else if ("lt".equals(currentFieldName)) { to = parser.objectBytes(); includeUpper = false; } else if ("lte".equals(currentFieldName) || "le".equals(currentFieldName)) { to = parser.objectBytes(); includeUpper = true; } else { throw new QueryParsingException( parseContext.index(), "[range] filter does not support [" + currentFieldName + "]"); } } } } else if (token.isValue()) { 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 { throw new QueryParsingException( parseContext.index(), "[range] filter does not support [" + currentFieldName + "]"); } } } if (fieldName == null) { throw new QueryParsingException(parseContext.index(), "No field specified for range filter"); } Filter filter = null; MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers != null) { if (smartNameFieldMappers.hasMapper()) { filter = smartNameFieldMappers .mapper() .rangeFilter(from, to, includeLower, includeUpper, parseContext); } } if (filter == null) { filter = new TermRangeFilter( fieldName, BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to), includeLower, includeUpper); } if (cache) { filter = parseContext.cacheFilter(filter, cacheKey); } filter = wrapSmartNameFilter(filter, smartNameFieldMappers, parseContext); if (filterName != null) { parseContext.addNamedFilter(filterName, filter); } return filter; }
@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; }
@Override public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); String fieldName = null; ShapeRelation shapeRelation = ShapeRelation.INTERSECTS; String strategyName = null; ShapeBuilder shape = null; FilterCachingPolicy cache = parseContext.autoFilterCachePolicy(); HashedBytesRef cacheKey = null; String filterName = null; String id = null; String type = null; String index = DEFAULTS.INDEX_NAME; String shapePath = DEFAULTS.SHAPE_FIELD_NAME; 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 (token == XContentParser.Token.START_OBJECT) { fieldName = currentFieldName; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); token = parser.nextToken(); if ("shape".equals(currentFieldName)) { shape = ShapeBuilder.parse(parser); } else if ("relation".equals(currentFieldName)) { shapeRelation = ShapeRelation.getRelationByName(parser.text()); if (shapeRelation == null) { throw new QueryParsingException( parseContext.index(), "Unknown shape operation [" + parser.text() + "]"); } } else if ("strategy".equals(currentFieldName)) { strategyName = parser.text(); } else if ("indexed_shape".equals(currentFieldName) || "indexedShape".equals(currentFieldName)) { while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token.isValue()) { if ("id".equals(currentFieldName)) { id = parser.text(); } else if ("type".equals(currentFieldName)) { type = parser.text(); } else if ("index".equals(currentFieldName)) { index = parser.text(); } else if ("path".equals(currentFieldName)) { shapePath = parser.text(); } } } if (id == null) { throw new QueryParsingException( parseContext.index(), "ID for indexed shape not provided"); } else if (type == null) { throw new QueryParsingException( parseContext.index(), "Type for indexed shape not provided"); } shape = fetchService.fetch(id, type, index, shapePath); } else { throw new QueryParsingException( parseContext.index(), "[geo_shape] filter does not support [" + currentFieldName + "]"); } } } } else if (token.isValue()) { if ("_name".equals(currentFieldName)) { filterName = parser.text(); } else if ("_cache".equals(currentFieldName)) { cache = parseContext.parseFilterCachePolicy(); } else if ("_cache_key".equals(currentFieldName)) { cacheKey = new HashedBytesRef(parser.text()); } else { throw new QueryParsingException( parseContext.index(), "[geo_shape] filter does not support [" + currentFieldName + "]"); } } } if (shape == null) { throw new QueryParsingException(parseContext.index(), "No Shape defined"); } else if (shapeRelation == null) { throw new QueryParsingException(parseContext.index(), "No Shape Relation defined"); } MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers == null || !smartNameFieldMappers.hasMapper()) { throw new QueryParsingException( parseContext.index(), "Failed to find geo_shape field [" + fieldName + "]"); } FieldMapper fieldMapper = smartNameFieldMappers.mapper(); // TODO: This isn't the nicest way to check this if (!(fieldMapper instanceof GeoShapeFieldMapper)) { throw new QueryParsingException( parseContext.index(), "Field [" + fieldName + "] is not a geo_shape"); } GeoShapeFieldMapper shapeFieldMapper = (GeoShapeFieldMapper) fieldMapper; PrefixTreeStrategy strategy = shapeFieldMapper.defaultStrategy(); if (strategyName != null) { strategy = shapeFieldMapper.resolveStrategy(strategyName); } Filter filter; if (strategy instanceof RecursivePrefixTreeStrategy && shapeRelation == ShapeRelation.DISJOINT) { // this strategy doesn't support disjoint anymore: but it did before, including creating // lucene fieldcache (!) // in this case, execute disjoint as exists && !intersects XBooleanFilter bool = new XBooleanFilter(); Filter exists = ExistsFilterParser.newFilter(parseContext, fieldName, null); Filter intersects = strategy.makeFilter(GeoShapeQueryParser.getArgs(shape, ShapeRelation.INTERSECTS)); bool.add(exists, BooleanClause.Occur.MUST); bool.add(intersects, BooleanClause.Occur.MUST_NOT); filter = bool; } else { filter = strategy.makeFilter(GeoShapeQueryParser.getArgs(shape, shapeRelation)); } if (cache != null) { filter = parseContext.cacheFilter(filter, cacheKey, cache); } if (filterName != null) { parseContext.addNamedFilter(filterName, filter); } return filter; }
@Override public Query parse(JsonQueryParseContext parseContext) throws IOException, QueryParsingException { JsonParser jp = parseContext.jp(); JsonToken token = jp.nextToken(); assert token == JsonToken.FIELD_NAME; String fieldName = jp.getCurrentName(); String from = null; String to = null; boolean includeLower = true; boolean includeUpper = true; float boost = 1.0f; String currentFieldName = null; while ((token = jp.nextToken()) != JsonToken.END_OBJECT) { if (token == JsonToken.FIELD_NAME) { currentFieldName = jp.getCurrentName(); } else { if ("from".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { from = null; } else { from = jp.getText(); } } else if ("to".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { to = null; } else { to = jp.getText(); } } else if ("include_lower".equals(currentFieldName)) { if (token == JsonToken.VALUE_NUMBER_INT) { includeLower = jp.getIntValue() != 0; } else if (token == JsonToken.VALUE_STRING) { includeLower = Booleans.parseBoolean(jp.getText(), includeLower); } else { includeLower = token == JsonToken.VALUE_TRUE; } } else if ("include_upper".equals(currentFieldName)) { if (token == JsonToken.VALUE_NUMBER_INT) { includeUpper = jp.getIntValue() != 0; } else if (token == JsonToken.VALUE_STRING) { includeUpper = Booleans.parseBoolean(jp.getText(), includeUpper); } else { includeUpper = token == JsonToken.VALUE_TRUE; } } else if ("boost".equals(currentFieldName)) { if (token == JsonToken.VALUE_STRING) { boost = Float.parseFloat(jp.getText()); } else { boost = jp.getFloatValue(); } } else if ("gt".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { from = null; } else { from = jp.getText(); } includeLower = false; } else if ("gte".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { from = null; } else { from = jp.getText(); } includeLower = true; } else if ("lt".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { to = null; } else { to = jp.getText(); } includeUpper = false; } else if ("lte".equals(currentFieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_NULL) { to = null; } else { to = jp.getText(); } includeUpper = true; } } } // move to the next end object, to close the field name token = jp.nextToken(); assert token == JsonToken.END_OBJECT; Query query = null; MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers != null) { if (smartNameFieldMappers.hasMapper()) { query = smartNameFieldMappers.mapper().rangeQuery(from, to, includeLower, includeUpper); } } if (query == null) { query = new TermRangeQuery(fieldName, from, to, includeLower, includeUpper); } query.setBoost(boost); return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext.indexCache()); }
@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); } } }