Skip to content

WIP First draft for version field #58256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
import org.elasticsearch.index.mapper.NumberFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.RangeFieldMapper;
import org.elasticsearch.index.mapper.RangeType;
import org.elasticsearch.index.mapper.BasicRangeType;
import org.elasticsearch.index.mapper.TextSearchInfo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostingQueryBuilder;
Expand Down Expand Up @@ -129,7 +129,7 @@ public PercolatorFieldMapper build(BuilderContext context) {
fieldType.queryBuilderField = queryBuilderField.fieldType();
// Range field is of type ip, because that matches closest with BinaryRange field. Otherwise we would
// have to introduce a new field type...
RangeFieldMapper rangeFieldMapper = createExtractedRangeFieldBuilder(RANGE_FIELD_NAME, RangeType.IP, context);
RangeFieldMapper rangeFieldMapper = createExtractedRangeFieldBuilder(RANGE_FIELD_NAME, BasicRangeType.IP, context);
fieldType.rangeField = rangeFieldMapper.fieldType();
NumberFieldMapper minimumShouldMatchFieldMapper = createMinimumShouldMatchField(context);
fieldType.minimumShouldMatchField = minimumShouldMatchFieldMapper.fieldType();
Expand Down Expand Up @@ -159,7 +159,7 @@ static BinaryFieldMapper createQueryBuilderFieldBuilder(BuilderContext context)
return builder.build(context);
}

static RangeFieldMapper createExtractedRangeFieldBuilder(String name, RangeType rangeType, BuilderContext context) {
static RangeFieldMapper createExtractedRangeFieldBuilder(String name, BasicRangeType rangeType, BuilderContext context) {
RangeFieldMapper.Builder builder = new RangeFieldMapper.Builder(name, rangeType);
// For now no doc values, because in processQuery(...) only the Lucene range fields get added:
builder.docValues(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.lucene.document;

import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FutureArrays;

public class Binary16RangeField extends Field {

public static final int BYTES = 16;

private static final FieldType TYPE;
static {
TYPE = new FieldType();
TYPE.setDimensions(2, BYTES);
TYPE.freeze();
}

public Binary16RangeField(String name, final BytesRef min, final BytesRef max) {
super(name, TYPE);
setRangeValues(min, max);
}

/**
* Change (or set) the min/max values of the field.
* @param min range min value
* @param max range max value
*/
public void setRangeValues(BytesRef min, BytesRef max) {
final byte[] bytes;
if (fieldsData == null) {
bytes = new byte[BYTES * 2];
fieldsData = new BytesRef(bytes);
} else {
bytes = ((BytesRef) fieldsData).bytes;
}
encode(min, max, bytes);
}

/** encode the min/max range into the provided byte array */
private static void encode(final BytesRef min, final BytesRef max, final byte[] bytes) {
int minBytesLength = Math.min(min.length, BYTES);
int maxBytesLength = Math.min(max.length, BYTES);
if (FutureArrays.compareUnsigned(min.bytes, min.offset, min.offset + minBytesLength,
max.bytes, max.offset, max.offset + maxBytesLength) > 0) {
throw new IllegalArgumentException("min value cannot be greater than max value for version field");
}
System.arraycopy(min.bytes, 0 + min.offset, bytes, 0, minBytesLength);
System.arraycopy(max.bytes, 0 + max.offset, bytes, BYTES, maxBytesLength);
}

/** encode the min/max range and return the byte array */
private static byte[] encode(BytesRef min, BytesRef max) {
byte[] b = new byte[BYTES*2];
encode(min, max, b);
return b;
}

public static Query newIntersectsQuery(String field, BytesRef from, BytesRef to, Query dvQuery) {
return newRelationQuery(field, from, to, RangeFieldQuery.QueryType.INTERSECTS, dvQuery);
}

public static Query newWithinQuery(String field, BytesRef from, BytesRef to, Query dvQuery) {
return newRelationQuery(field, from, to, RangeFieldQuery.QueryType.WITHIN, dvQuery);
}

public static Query newContainsQuery(String field, BytesRef from, BytesRef to, Query dvQuery) {
return newRelationQuery(field, from, to, RangeFieldQuery.QueryType.CONTAINS, dvQuery);
}

/** helper method for creating the desired relational query */
private static Query newRelationQuery(
String field,
final BytesRef min,
final BytesRef max,
RangeFieldQuery.QueryType relation,
Query dvQuery
) {
RangeFieldQuery rangeFieldQuery = new RangeFieldQuery(field, encode(min, max), 1, relation) {
@Override
protected String toString(byte[] ranges, int dimension) {
return Binary16RangeField.toString(ranges, dimension);
}
};
BooleanQuery conjunctionQuery = new BooleanQuery.Builder().add(new BooleanClause(rangeFieldQuery, Occur.MUST))
.add(new BooleanClause(dvQuery, Occur.MUST)).build();
return conjunctionQuery;
}

/**
* Returns the String representation for the range at the given dimension
* @param ranges the encoded ranges, never null
* @param dimension the dimension of interest (not used for this field)
* @return The string representation for the range at the provided dimension
*/
private static String toString(byte[] ranges, int dimension) {
byte[] min = new byte[BYTES];
System.arraycopy(ranges, 0, min, 0, BYTES);
byte[] max = new byte[BYTES];
System.arraycopy(ranges, BYTES, max, 0, BYTES);
return "[" + new BytesRef(min) + " : " + new BytesRef(max) + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.apache.lucene.search.Weight;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.index.mapper.RangeType;
import org.elasticsearch.index.mapper.BasicRangeType;

import java.io.IOException;
import java.util.Objects;
Expand All @@ -41,13 +41,13 @@ public final class BinaryDocValuesRangeQuery extends Query {

private final String fieldName;
private final QueryType queryType;
private final RangeType.LengthType lengthType;
private final BasicRangeType.LengthType lengthType;
private final BytesRef from;
private final BytesRef to;
private final Object originalFrom;
private final Object originalTo;

public BinaryDocValuesRangeQuery(String fieldName, QueryType queryType, RangeType.LengthType lengthType,
public BinaryDocValuesRangeQuery(String fieldName, QueryType queryType, BasicRangeType.LengthType lengthType,
BytesRef from, BytesRef to,
Object originalFrom, Object originalTo) {
this.fieldName = fieldName;
Expand Down Expand Up @@ -87,11 +87,13 @@ public boolean matches() throws IOException {
int offset = in.getPosition();
for (int i = 0; i < numRanges; i++) {
int length = lengthType.readLength(bytes, offset);
offset += lengthType.advanceBy();
otherFrom.offset = offset;
otherFrom.length = length;
offset += length;

length = lengthType.readLength(bytes, offset);
offset += lengthType.advanceBy();
otherTo.offset = offset;
otherTo.length = length;
offset += length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,13 @@ private static boolean[] grow(boolean[] array, int minSize) {

}

abstract static class BinaryScriptDocValues<T> extends ScriptDocValues<T> {
public abstract static class BinaryScriptDocValues<T> extends ScriptDocValues<T> {

private final SortedBinaryDocValues in;
protected BytesRefBuilder[] values = new BytesRefBuilder[0];
protected int count;

BinaryScriptDocValues(SortedBinaryDocValues in) {
public BinaryScriptDocValues(SortedBinaryDocValues in) {
this.in = in;
}

Expand Down
Loading