@Override public List<Field> createFields(String name, Number value, boolean indexed, boolean docValued, boolean stored) { List<Field> fields = new ArrayList<>(); if (indexed) { fields.add(new FloatPoint(name, value.floatValue())); } if (docValued) { fields.add(new SortedNumericDocValuesField(name, NumericUtils.floatToSortableInt(value.floatValue()))); } if (stored) { fields.add(new StoredField(name, value.floatValue())); } return fields; }
@Override FieldStats.Double stats(IndexReader reader, String fieldName, boolean isSearchable, boolean isAggregatable) throws IOException { FieldInfo fi = org.apache.lucene.index.MultiFields.getMergedFieldInfos(reader).fieldInfo(fieldName); if (fi == null) { return null; } long size = PointValues.size(reader, fieldName); if (size == 0) { return new FieldStats.Double(reader.maxDoc(), 0, -1, -1, isSearchable, isAggregatable); } int docCount = PointValues.getDocCount(reader, fieldName); byte[] min = PointValues.getMinPackedValue(reader, fieldName); byte[] max = PointValues.getMaxPackedValue(reader, fieldName); return new FieldStats.Double(reader.maxDoc(),docCount, -1L, size, isSearchable, isAggregatable, FloatPoint.decodeDimension(min, 0), FloatPoint.decodeDimension(max, 0)); }
@Override Query termsQuery(String field, List<Object> values) { float[] v = new float[values.size()]; for (int i = 0; i < values.size(); ++i) { v[i] = parse(values.get(i), false); } return FloatPoint.newSetQuery(field, v); }
@Override Query rangeQuery(String field, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, boolean hasDocValues) { float l = Float.NEGATIVE_INFINITY; float u = Float.POSITIVE_INFINITY; if (lowerTerm != null) { l = parse(lowerTerm, false); if (includeLower == false) { l = FloatPoint.nextUp(l); } } if (upperTerm != null) { u = parse(upperTerm, false); if (includeUpper == false) { u = FloatPoint.nextDown(u); } } Query query = FloatPoint.newRangeQuery(field, l, u); if (hasDocValues) { Query dvQuery = SortedNumericDocValuesField.newRangeQuery(field, NumericUtils.floatToSortableInt(l), NumericUtils.floatToSortableInt(u)); query = new IndexOrDocValuesQuery(query, dvQuery); } return query; }
private void addAdditionalFilter(BooleanQuery.Builder builder, Map.Entry<String, Object> entry) { String key = entry.getKey().toLowerCase(); if (entry.getValue() instanceof List) { addFiltersFromList(builder, entry, key); } else if (entry.getValue() instanceof Integer || entry.getValue() instanceof Long) { builder.add(IntPoint.newExactQuery(key, (Integer) entry.getValue()), BooleanClause.Occur.MUST); } else if (entry.getValue() instanceof Float || entry.getValue() instanceof Double) { builder.add(FloatPoint.newExactQuery(key, (Float) entry.getValue()), BooleanClause.Occur.MUST); } else { builder.add(new TermQuery(new Term(key, entry.getValue().toString().toLowerCase())), BooleanClause.Occur.MUST); } }
private void addQualityFilter(BooleanQuery.Builder builder) { if (quality != null && !quality.isEmpty()) { if (quality.size() < 2) { builder.add(FloatPoint.newExactQuery(FeatureIndexFields.QUALITY.getFieldName(), quality.get(0)), BooleanClause.Occur.MUST); } else { Assert.isTrue(quality.get(0) != null || quality.get(1) != null, "Incorrect filter parameter:" + " quality:[null, null]"); builder.add(FloatPoint.newRangeQuery(FeatureIndexFields.QUALITY.getFieldName(), quality.get(0) != null ? quality.get(0) : Float.MIN_VALUE, quality.get(1) != null ? quality.get(1) : Float.MAX_VALUE), BooleanClause.Occur.MUST); } } }
private void tryAddFloatingKeyFalueFilter(BooleanQuery.Builder builder, Map.Entry<String, Object> entry, String key, List list, Object val) { if (val instanceof Float || entry.getValue() instanceof Double) { builder.add(FloatPoint.newRangeQuery(key, list.get(0) != null ? (Float) list.get(0) : Float.MIN_VALUE, list.get(1) != null ? (Float) list.get(1) : Float.MAX_VALUE), BooleanClause.Occur.MUST); } }
private void tryAddFloatingFilter(BooleanQuery.Builder builder, Map.Entry<String, Object> entry, String key, Object val) { if (val instanceof Float || entry.getValue() instanceof Double) { builder.add(FloatPoint.newExactQuery(key, (Float) entry.getValue()), BooleanClause.Occur.MUST); } }
private static BytesRef pack(float... point) { if (point == null) { throw new IllegalArgumentException("point cannot be null"); } if (point.length == 0) { throw new IllegalArgumentException("point cannot be 0 dimensions"); } byte[] packed = new byte[point.length * Float.BYTES]; for (int dim = 0; dim < point.length; dim++) { FloatPoint.encodeDimension(point[dim], packed, dim * Float.BYTES); } return new BytesRef(packed); }
@Override Query termQuery(String field, Object value) { float v = parse(value, false); return FloatPoint.newExactQuery(field, v); }
public void testHalfFloatRange() throws IOException { // make sure the accuracy loss of half floats only occurs at index time // this test checks that searching half floats yields the same results as // searching floats that are rounded to the closest half float Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null)); final int numDocs = 10000; for (int i = 0; i < numDocs; ++i) { Document doc = new Document(); float value = (randomFloat() * 2 - 1) * 70000; float rounded = HalfFloatPoint.sortableShortToHalfFloat(HalfFloatPoint.halfFloatToSortableShort(value)); doc.add(new HalfFloatPoint("half_float", value)); doc.add(new FloatPoint("float", rounded)); w.addDocument(doc); } final DirectoryReader reader = DirectoryReader.open(w); w.close(); IndexSearcher searcher = newSearcher(reader); final int numQueries = 1000; for (int i = 0; i < numQueries; ++i) { float l = (randomFloat() * 2 - 1) * 70000; float u = (randomFloat() * 2 - 1) * 70000; boolean includeLower = randomBoolean(); boolean includeUpper = randomBoolean(); Query floatQ = NumberFieldMapper.NumberType.FLOAT.rangeQuery("float", l, u, includeLower, includeUpper, false); Query halfFloatQ = NumberFieldMapper.NumberType.HALF_FLOAT.rangeQuery("half_float", l, u, includeLower, includeUpper, false); assertEquals(searcher.count(floatQ), searcher.count(halfFloatQ)); } IOUtils.close(reader, dir); }
@Override protected Field createField(Number o, String indexedFieldName) { return new FloatPoint(indexedFieldName, o.floatValue()); }