Skip to content

Commit

Permalink
HSEARCH-4950 Update validation of vector-specific mapping attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
marko-bekhta committed Jan 15, 2024
1 parent f7ca3fe commit 5ae4212
Show file tree
Hide file tree
Showing 11 changed files with 356 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ public static Set<String> typesRequiringReflection() {
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMappingJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RootTypeMappingJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.AnalysisJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.IndexSettingsJsonAdapterFactory"
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.IndexSettingsJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptions",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethod",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethod$Parameters",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethodJsonAdapterFactory",
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethodJsonAdapterFactory$ParametersJsonAdapterFactory"
) );
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;

import java.util.Map;

import org.hibernate.search.backend.elasticsearch.gson.impl.SerializeExtraProperties;

import com.google.gson.JsonElement;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;

/**
* An object representing Elasticsearch dense vector-specific index options attributes.
*
* See https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
*/
/*
* CAUTION:
* 1. JSON serialization is controlled by a specific adapter, which must be
* updated whenever fields of this class are added, renamed or removed.
*
* 2. Whenever adding more properties consider adding property validation to PropertyMappingValidator#ElasticsearchDenseVectorIndexOptionsValidator.
*/
@JsonAdapter(ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory.class)
public class ElasticsearchDenseVectorIndexOptions {

private String type;

private Integer m;

@SerializedName("ef_construction")
private Integer efConstruction;

@SerializeExtraProperties
private Map<String, JsonElement> extraAttributes;

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public Integer getM() {
return m;
}

public void setM(Integer m) {
this.m = m;
}

public Integer getEfConstruction() {
return efConstruction;
}

public void setEfConstruction(Integer efConstruction) {
this.efConstruction = efConstruction;
}

public Map<String, JsonElement> getExtraAttributes() {
return extraAttributes;
}

public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
this.extraAttributes = extraAttributes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;

import org.hibernate.search.backend.elasticsearch.gson.impl.AbstractConfiguredExtraPropertiesJsonAdapterFactory;

public class ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory
extends
AbstractConfiguredExtraPropertiesJsonAdapterFactory {

@Override
protected <T> void addFields(Builder<T> builder) {
builder.add( "type", String.class );
builder.add( "m", Integer.class );
builder.add( "efConstruction", Integer.class );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;

import java.util.Map;

import org.hibernate.search.backend.elasticsearch.gson.impl.SerializeExtraProperties;

import com.google.gson.JsonElement;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;

/**
* An object representing OpenSearch K-NN vector Method attributes.
*
* See https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
*/
/*
* CAUTION:
* 1. JSON serialization is controlled by a specific adapter, which must be
* updated whenever fields of this class are added, renamed or removed.
*
* 2. Whenever adding more properties consider adding property validation to PropertyMappingValidator.
*/
@JsonAdapter(OpenSearchVectorTypeMethodJsonAdapterFactory.class)
public class OpenSearchVectorTypeMethod {

private String name;

@SerializedName("space_type")
private String spaceType;

private String engine;

private Parameters parameters;

@SerializeExtraProperties
private Map<String, JsonElement> extraAttributes;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSpaceType() {
return spaceType;
}

public void setSpaceType(String spaceType) {
this.spaceType = spaceType;
}

public String getEngine() {
return engine;
}

public void setEngine(String engine) {
this.engine = engine;
}

public Parameters getParameters() {
return parameters;
}

public void setParameters(Parameters parameters) {
this.parameters = parameters;
}

public Map<String, JsonElement> getExtraAttributes() {
return extraAttributes;
}

public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
this.extraAttributes = extraAttributes;
}

@JsonAdapter(OpenSearchVectorTypeMethodJsonAdapterFactory.ParametersJsonAdapterFactory.class)
public static class Parameters {

@SerializedName("ef_construction")
private Integer efConstruction;
private Integer m;

@SerializeExtraProperties
private Map<String, JsonElement> extraAttributes;

public Integer getEfConstruction() {
return efConstruction;
}

public void setEfConstruction(Integer efConstruction) {
this.efConstruction = efConstruction;
}

public Integer getM() {
return m;
}

public void setM(Integer m) {
this.m = m;
}

public Map<String, JsonElement> getExtraAttributes() {
return extraAttributes;
}

public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
this.extraAttributes = extraAttributes;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;

import org.hibernate.search.backend.elasticsearch.gson.impl.AbstractConfiguredExtraPropertiesJsonAdapterFactory;

public class OpenSearchVectorTypeMethodJsonAdapterFactory
extends
AbstractConfiguredExtraPropertiesJsonAdapterFactory {

@Override
protected <T> void addFields(Builder<T> builder) {
builder.add( "name", String.class );
builder.add( "spaceType", String.class );
builder.add( "engine", String.class );
builder.add( "parameters", OpenSearchVectorTypeMethod.Parameters.class );
}

public static class ParametersJsonAdapterFactory
extends
AbstractConfiguredExtraPropertiesJsonAdapterFactory {
@Override
protected <T> void addFields(Builder<T> builder) {
builder.add( "m", Integer.class );
builder.add( "efConstruction", Integer.class );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public class PropertyMapping extends AbstractTypeMapping {
* https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
*/
@SerializedName("index_options")
private JsonElement indexOptions;
private ElasticsearchDenseVectorIndexOptions indexOptions;

/*
* k-NN vector datatype
Expand All @@ -125,7 +125,7 @@ public class PropertyMapping extends AbstractTypeMapping {
* k-NN vector datatype
* https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
*/
private JsonElement method;
private OpenSearchVectorTypeMethod method;

/*
* k-NN vector datatype
Expand Down Expand Up @@ -247,11 +247,11 @@ public void setSimilarity(String similarity) {
this.similarity = similarity;
}

public JsonElement getIndexOptions() {
public ElasticsearchDenseVectorIndexOptions getIndexOptions() {
return indexOptions;
}

public void setIndexOptions(JsonElement indexOptions) {
public void setIndexOptions(ElasticsearchDenseVectorIndexOptions indexOptions) {
this.indexOptions = indexOptions;
}

Expand All @@ -263,11 +263,11 @@ public void setDimension(Integer dimension) {
this.dimension = dimension;
}

public JsonElement getMethod() {
public OpenSearchVectorTypeMethod getMethod() {
return method;
}

public void setMethod(JsonElement method) {
public void setMethod(OpenSearchVectorTypeMethod method) {
this.method = method;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ protected <T> void addFields(Builder<T> builder) {
builder.add( "elementType", String.class );
builder.add( "dims", Integer.class );
builder.add( "similarity", String.class );
builder.add( "indexOptions", JsonElement.class );
builder.add( "indexOptions", ElasticsearchDenseVectorIndexOptions.class );
builder.add( "dimension", Integer.class );
builder.add( "method", JsonElement.class );
builder.add( "method", OpenSearchVectorTypeMethod.class );
builder.add( "dataType", String.class );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
package org.hibernate.search.backend.elasticsearch.types.mapping.impl;

import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.DataTypes;
import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptions;
import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMapping;
import org.hibernate.search.backend.elasticsearch.search.predicate.impl.ElasticsearchKnnPredicate;
import org.hibernate.search.backend.elasticsearch.types.impl.ElasticsearchIndexValueFieldType;
import org.hibernate.search.engine.backend.types.VectorSimilarity;
import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys;
import org.hibernate.search.util.common.AssertionFailure;

import com.google.gson.JsonObject;

public class Elasticsearch8VectorFieldTypeMappingContributor implements ElasticsearchVectorFieldTypeMappingContributor {
@Override
public void contribute(PropertyMapping mapping, Context context) {
Expand All @@ -27,13 +26,13 @@ public void contribute(PropertyMapping mapping, Context context) {
mapping.setSimilarity( resolvedVectorSimilarity );
}
if ( context.maxConnections() != null || context.beamWidth() != null ) {
JsonObject indexOptions = new JsonObject();
indexOptions.addProperty( "type", "hnsw" );
ElasticsearchDenseVectorIndexOptions indexOptions = new ElasticsearchDenseVectorIndexOptions();
indexOptions.setType( "hnsw" );
if ( context.maxConnections() != null ) {
indexOptions.addProperty( "m", context.maxConnections() );
indexOptions.setM( context.maxConnections() );
}
if ( context.beamWidth() != null ) {
indexOptions.addProperty( "ef_construction", context.beamWidth() );
indexOptions.setEfConstruction( context.beamWidth() );
}
mapping.setIndexOptions( indexOptions );
}
Expand Down
Loading

0 comments on commit 5ae4212

Please sign in to comment.