Skip to content

Commit

Permalink
Merge branch 'main' into refactoring/remove_mapper_merge_context_root
Browse files Browse the repository at this point in the history
  • Loading branch information
javanna committed Jun 20, 2024
2 parents fa94aac + cfd873c commit 698cfdd
Show file tree
Hide file tree
Showing 72 changed files with 1,000 additions and 438 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ private void logFileContents(String description, Path from, boolean tailLogs) {
}
}
if (foundLeaks) {
throw new TestClustersException("Found resource leaks in node logs.");
throw new TestClustersException("Found resource leaks in node log: " + from);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,24 +748,4 @@ public static XContentParser mapToXContentParser(XContentParserConfiguration con
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
}
}

/**
* Drains all data available via this parser into a provided builder.
* Provided parser is closed as a result.
* @param parser
* @param destination
*/
public static void drainAndClose(XContentParser parser, XContentBuilder destination) throws IOException {
if (parser.isClosed()) {
throw new IllegalStateException("Can't drain a parser that is closed");
}

XContentParser.Token token;
do {
destination.copyCurrentStructure(parser);
token = parser.nextToken();
} while (token != null);

parser.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ public static MapperBuilderContext root(boolean isSourceSynthetic, boolean isDat
private final ObjectMapper.Dynamic dynamic;
private final MergeReason mergeReason;

MapperBuilderContext(String path) {
this(path, false, false, false, ObjectMapper.Defaults.DYNAMIC, MergeReason.MAPPING_UPDATE);
}

MapperBuilderContext(
String path,
boolean isSourceSynthetic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@
import org.apache.lucene.index.SegmentWriteState;
import org.apache.lucene.index.VectorEncoding;
import org.apache.lucene.index.VectorSimilarityFunction;
import org.apache.lucene.queries.function.FunctionQuery;
import org.apache.lucene.queries.function.valuesource.ByteKnnVectorFieldSource;
import org.apache.lucene.queries.function.valuesource.ByteVectorSimilarityFunction;
import org.apache.lucene.queries.function.valuesource.ConstKnnByteVectorValueSource;
import org.apache.lucene.queries.function.valuesource.ConstKnnFloatValueSource;
import org.apache.lucene.queries.function.valuesource.FloatKnnVectorFieldSource;
import org.apache.lucene.queries.function.valuesource.FloatVectorSimilarityFunction;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FieldExistsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.BitSetProducer;
Expand Down Expand Up @@ -67,6 +58,7 @@
import org.elasticsearch.index.query.SearchExecutionContext;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.vectors.DenseVectorQuery;
import org.elasticsearch.search.vectors.ESDiversifyingChildrenByteKnnVectorQuery;
import org.elasticsearch.search.vectors.ESDiversifyingChildrenFloatKnnVectorQuery;
import org.elasticsearch.search.vectors.ESKnnByteVectorQuery;
Expand Down Expand Up @@ -1484,19 +1476,7 @@ private Query createExactKnnByteQuery(byte[] queryVector) {
float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector);
elementType.checkVectorMagnitude(similarity, ElementType.errorByteElementsAppender(queryVector), squaredMagnitude);
}
VectorSimilarityFunction vectorSimilarityFunction = similarity.vectorSimilarityFunction(indexVersionCreated, elementType);
return new BooleanQuery.Builder().add(new FieldExistsQuery(name()), BooleanClause.Occur.FILTER)
.add(
new FunctionQuery(
new ByteVectorSimilarityFunction(
vectorSimilarityFunction,
new ByteKnnVectorFieldSource(name()),
new ConstKnnByteVectorValueSource(queryVector)
)
),
BooleanClause.Occur.SHOULD
)
.build();
return new DenseVectorQuery.Bytes(queryVector, name());
}

private Query createExactKnnFloatQuery(float[] queryVector) {
Expand All @@ -1519,19 +1499,7 @@ && isNotUnitVector(squaredMagnitude)) {
}
}
}
VectorSimilarityFunction vectorSimilarityFunction = similarity.vectorSimilarityFunction(indexVersionCreated, elementType);
return new BooleanQuery.Builder().add(new FieldExistsQuery(name()), BooleanClause.Occur.FILTER)
.add(
new FunctionQuery(
new FloatVectorSimilarityFunction(
vectorSimilarityFunction,
new FloatKnnVectorFieldSource(name()),
new ConstKnnFloatValueSource(queryVector)
)
),
BooleanClause.Occur.SHOULD
)
.build();
return new DenseVectorQuery.Floats(queryVector, name());
}

Query createKnnQuery(float[] queryVector, int numCands, Query filter, Float similarityThreshold, BitSetProducer parentFilter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.search.vectors;

import org.apache.lucene.index.ByteVectorValues;
import org.apache.lucene.index.FloatVectorValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.VectorScorer;
import org.apache.lucene.search.Weight;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
* Exact knn query. Will iterate and score all documents that have the provided dense vector field in the index.
*/
public abstract class DenseVectorQuery extends Query {

protected final String field;

public DenseVectorQuery(String field) {
this.field = field;
}

@Override
public void visit(QueryVisitor queryVisitor) {
queryVisitor.visitLeaf(this);
}

abstract static class DenseVectorWeight extends Weight {
private final String field;
private final float boost;

protected DenseVectorWeight(DenseVectorQuery query, float boost) {
super(query);
this.field = query.field;
this.boost = boost;
}

abstract VectorScorer vectorScorer(LeafReaderContext leafReaderContext) throws IOException;

@Override
public Explanation explain(LeafReaderContext leafReaderContext, int i) throws IOException {
VectorScorer vectorScorer = vectorScorer(leafReaderContext);
if (vectorScorer == null) {
return Explanation.noMatch("No vector values found for field: " + field);
}
DocIdSetIterator iterator = vectorScorer.iterator();
iterator.advance(i);
if (iterator.docID() == i) {
float score = vectorScorer.score();
return Explanation.match(vectorScorer.score() * boost, "found vector with calculated similarity: " + score);
}
return Explanation.noMatch("Document not found in vector values for field: " + field);
}

@Override
public Scorer scorer(LeafReaderContext leafReaderContext) throws IOException {
VectorScorer vectorScorer = vectorScorer(leafReaderContext);
if (vectorScorer == null) {
return null;
}
return new DenseVectorScorer(this, vectorScorer);
}

@Override
public boolean isCacheable(LeafReaderContext leafReaderContext) {
return true;
}
}

public static class Floats extends DenseVectorQuery {

private final float[] query;

public Floats(float[] query, String field) {
super(field);
this.query = query;
}

public float[] getQuery() {
return query;
}

@Override
public String toString(String field) {
return "DenseVectorQuery.Floats";
}

@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new DenseVectorWeight(Floats.this, boost) {
@Override
VectorScorer vectorScorer(LeafReaderContext leafReaderContext) throws IOException {
FloatVectorValues vectorValues = leafReaderContext.reader().getFloatVectorValues(field);
if (vectorValues == null) {
return null;
}
return vectorValues.scorer(query);
}
};
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Floats floats = (Floats) o;
return Objects.equals(field, floats.field) && Objects.deepEquals(query, floats.query);
}

@Override
public int hashCode() {
return Objects.hash(field, Arrays.hashCode(query));
}
}

public static class Bytes extends DenseVectorQuery {

private final byte[] query;

public Bytes(byte[] query, String field) {
super(field);
this.query = query;
}

@Override
public String toString(String field) {
return "DenseVectorQuery.Bytes";
}

@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new DenseVectorWeight(Bytes.this, boost) {
@Override
VectorScorer vectorScorer(LeafReaderContext leafReaderContext) throws IOException {
ByteVectorValues vectorValues = leafReaderContext.reader().getByteVectorValues(field);
if (vectorValues == null) {
return null;
}
return vectorValues.scorer(query);
}
};
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Bytes bytes = (Bytes) o;
return Objects.equals(field, bytes.field) && Objects.deepEquals(query, bytes.query);
}

@Override
public int hashCode() {
return Objects.hash(field, Arrays.hashCode(query));
}
}

static class DenseVectorScorer extends Scorer {

private final VectorScorer vectorScorer;
private final DocIdSetIterator iterator;
private final float boost;

DenseVectorScorer(DenseVectorWeight weight, VectorScorer vectorScorer) {
super(weight);
this.vectorScorer = vectorScorer;
this.iterator = vectorScorer.iterator();
this.boost = weight.boost;
}

@Override
public DocIdSetIterator iterator() {
return vectorScorer.iterator();
}

@Override
public float getMaxScore(int i) throws IOException {
// TODO: can we optimize this at all?
return Float.POSITIVE_INFINITY;
}

@Override
public float score() throws IOException {
assert iterator.docID() != -1;
return vectorScorer.score() * boost;
}

@Override
public int docID() {
return iterator.docID();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

package org.elasticsearch.common.xcontent.support;

import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressedXContent;
Expand Down Expand Up @@ -421,25 +420,4 @@ public void testParseToType() throws IOException {

assertThat(names, equalTo(Set.of("a", "c")));
}

public void testDrainAndClose() throws IOException {
String json = """
{ "a": "b", "c": "d", "e": {"f": "g"}, "h": ["i", "j", {"k": "l"}]}""";
var parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, json);
var content = XContentBuilder.builder(XContentType.JSON.xContent());
XContentHelper.drainAndClose(parser, content);

assertEquals(json.replace(" ", ""), Strings.toString(content));
assertTrue(parser.isClosed());
}

public void testDrainAndCloseAlreadyClosed() throws IOException {
var parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, "{}");
parser.close();

assertThrows(
IllegalStateException.class,
() -> XContentHelper.drainAndClose(parser, XContentBuilder.builder(XContentType.JSON.xContent()))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public void testFieldAliasWithDifferentNestedScopes() {

private static FieldMapper createFieldMapper(String parent, String name) {
return new BooleanFieldMapper.Builder(name, ScriptCompiler.NONE, false, IndexVersion.current()).build(
new MapperBuilderContext(parent)
new MapperBuilderContext(parent, false, false, false, ObjectMapper.Defaults.DYNAMIC, MapperService.MergeReason.MAPPING_UPDATE)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,16 @@ private static RootObjectMapper createRootSubobjectFalseLeafWithDots() {

private static ObjectMapper.Builder createObjectSubobjectsFalseLeafWithDots() {
KeywordFieldMapper.Builder fieldBuilder = new KeywordFieldMapper.Builder("host.name", IndexVersion.current());
KeywordFieldMapper fieldMapper = fieldBuilder.build(new MapperBuilderContext("foo.metrics"));
KeywordFieldMapper fieldMapper = fieldBuilder.build(
new MapperBuilderContext(
"foo.metrics",
false,
false,
false,
ObjectMapper.Defaults.DYNAMIC,
MapperService.MergeReason.MAPPING_UPDATE
)
);
assertEquals("host.name", fieldMapper.simpleName());
assertEquals("foo.metrics.host.name", fieldMapper.name());
return new ObjectMapper.Builder("foo", ObjectMapper.Defaults.SUBOBJECTS).add(
Expand All @@ -342,7 +351,16 @@ private static ObjectMapper.Builder createObjectSubobjectsFalseLeafWithDots() {

private ObjectMapper.Builder createObjectSubobjectsFalseLeafWithMultiField() {
TextFieldMapper.Builder fieldBuilder = createTextKeywordMultiField("host.name");
TextFieldMapper textKeywordMultiField = fieldBuilder.build(new MapperBuilderContext("foo.metrics"));
TextFieldMapper textKeywordMultiField = fieldBuilder.build(
new MapperBuilderContext(
"foo.metrics",
false,
false,
false,
ObjectMapper.Defaults.DYNAMIC,
MapperService.MergeReason.MAPPING_UPDATE
)
);
assertEquals("host.name", textKeywordMultiField.simpleName());
assertEquals("foo.metrics.host.name", textKeywordMultiField.name());
FieldMapper fieldMapper = textKeywordMultiField.multiFields.iterator().next();
Expand Down
Loading

0 comments on commit 698cfdd

Please sign in to comment.