Skip to content

Commit c378ce6

Browse files
committed
HSEARCH-4950 Update validation of vector-specific mapping attributes
1 parent 187b815 commit c378ce6

File tree

11 files changed

+356
-87
lines changed

11 files changed

+356
-87
lines changed

backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/gson/spi/GsonClasses.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ public static Set<String> typesRequiringReflection() {
5454
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMappingJsonAdapterFactory",
5555
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RootTypeMappingJsonAdapterFactory",
5656
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.AnalysisJsonAdapterFactory",
57-
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.IndexSettingsJsonAdapterFactory"
57+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.IndexSettingsJsonAdapterFactory",
58+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptions",
59+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethod",
60+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethod$Parameters",
61+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory",
62+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethodJsonAdapterFactory",
63+
"org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.OpenSearchVectorTypeMethodJsonAdapterFactory$ParametersJsonAdapterFactory"
5864
) );
5965
}
6066

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;
8+
9+
import java.util.Map;
10+
11+
import org.hibernate.search.backend.elasticsearch.gson.impl.SerializeExtraProperties;
12+
13+
import com.google.gson.JsonElement;
14+
import com.google.gson.annotations.JsonAdapter;
15+
import com.google.gson.annotations.SerializedName;
16+
17+
/**
18+
* An object representing Elasticsearch dense vector-specific index options attributes.
19+
*
20+
* See https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
21+
*/
22+
/*
23+
* CAUTION:
24+
* 1. JSON serialization is controlled by a specific adapter, which must be
25+
* updated whenever fields of this class are added, renamed or removed.
26+
*
27+
* 2. Whenever adding more properties consider adding property validation to PropertyMappingValidator#ElasticsearchDenseVectorIndexOptionsValidator.
28+
*/
29+
@JsonAdapter(ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory.class)
30+
public class ElasticsearchDenseVectorIndexOptions {
31+
32+
private String type;
33+
34+
private Integer m;
35+
36+
@SerializedName("ef_construction")
37+
private Integer efConstruction;
38+
39+
@SerializeExtraProperties
40+
private Map<String, JsonElement> extraAttributes;
41+
42+
public String getType() {
43+
return type;
44+
}
45+
46+
public void setType(String type) {
47+
this.type = type;
48+
}
49+
50+
public Integer getM() {
51+
return m;
52+
}
53+
54+
public void setM(Integer m) {
55+
this.m = m;
56+
}
57+
58+
public Integer getEfConstruction() {
59+
return efConstruction;
60+
}
61+
62+
public void setEfConstruction(Integer efConstruction) {
63+
this.efConstruction = efConstruction;
64+
}
65+
66+
public Map<String, JsonElement> getExtraAttributes() {
67+
return extraAttributes;
68+
}
69+
70+
public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
71+
this.extraAttributes = extraAttributes;
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;
8+
9+
import org.hibernate.search.backend.elasticsearch.gson.impl.AbstractConfiguredExtraPropertiesJsonAdapterFactory;
10+
11+
public class ElasticsearchDenseVectorIndexOptionsJsonAdapterFactory
12+
extends
13+
AbstractConfiguredExtraPropertiesJsonAdapterFactory {
14+
15+
@Override
16+
protected <T> void addFields(Builder<T> builder) {
17+
builder.add( "type", String.class );
18+
builder.add( "m", Integer.class );
19+
builder.add( "efConstruction", Integer.class );
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;
8+
9+
import java.util.Map;
10+
11+
import org.hibernate.search.backend.elasticsearch.gson.impl.SerializeExtraProperties;
12+
13+
import com.google.gson.JsonElement;
14+
import com.google.gson.annotations.JsonAdapter;
15+
import com.google.gson.annotations.SerializedName;
16+
17+
/**
18+
* An object representing OpenSearch K-NN vector Method attributes.
19+
*
20+
* See https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
21+
*/
22+
/*
23+
* CAUTION:
24+
* 1. JSON serialization is controlled by a specific adapter, which must be
25+
* updated whenever fields of this class are added, renamed or removed.
26+
*
27+
* 2. Whenever adding more properties consider adding property validation to PropertyMappingValidator.
28+
*/
29+
@JsonAdapter(OpenSearchVectorTypeMethodJsonAdapterFactory.class)
30+
public class OpenSearchVectorTypeMethod {
31+
32+
private String name;
33+
34+
@SerializedName("space_type")
35+
private String spaceType;
36+
37+
private String engine;
38+
39+
private Parameters parameters;
40+
41+
@SerializeExtraProperties
42+
private Map<String, JsonElement> extraAttributes;
43+
44+
public String getName() {
45+
return name;
46+
}
47+
48+
public void setName(String name) {
49+
this.name = name;
50+
}
51+
52+
public String getSpaceType() {
53+
return spaceType;
54+
}
55+
56+
public void setSpaceType(String spaceType) {
57+
this.spaceType = spaceType;
58+
}
59+
60+
public String getEngine() {
61+
return engine;
62+
}
63+
64+
public void setEngine(String engine) {
65+
this.engine = engine;
66+
}
67+
68+
public Parameters getParameters() {
69+
return parameters;
70+
}
71+
72+
public void setParameters(Parameters parameters) {
73+
this.parameters = parameters;
74+
}
75+
76+
public Map<String, JsonElement> getExtraAttributes() {
77+
return extraAttributes;
78+
}
79+
80+
public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
81+
this.extraAttributes = extraAttributes;
82+
}
83+
84+
@JsonAdapter(OpenSearchVectorTypeMethodJsonAdapterFactory.ParametersJsonAdapterFactory.class)
85+
public static class Parameters {
86+
87+
@SerializedName("ef_construction")
88+
private Integer efConstruction;
89+
private Integer m;
90+
91+
@SerializeExtraProperties
92+
private Map<String, JsonElement> extraAttributes;
93+
94+
public Integer getEfConstruction() {
95+
return efConstruction;
96+
}
97+
98+
public void setEfConstruction(Integer efConstruction) {
99+
this.efConstruction = efConstruction;
100+
}
101+
102+
public Integer getM() {
103+
return m;
104+
}
105+
106+
public void setM(Integer m) {
107+
this.m = m;
108+
}
109+
110+
public Map<String, JsonElement> getExtraAttributes() {
111+
return extraAttributes;
112+
}
113+
114+
public void setExtraAttributes(Map<String, JsonElement> extraAttributes) {
115+
this.extraAttributes = extraAttributes;
116+
}
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Hibernate Search, full-text search for your domain model
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl;
8+
9+
import org.hibernate.search.backend.elasticsearch.gson.impl.AbstractConfiguredExtraPropertiesJsonAdapterFactory;
10+
11+
public class OpenSearchVectorTypeMethodJsonAdapterFactory
12+
extends
13+
AbstractConfiguredExtraPropertiesJsonAdapterFactory {
14+
15+
@Override
16+
protected <T> void addFields(Builder<T> builder) {
17+
builder.add( "name", String.class );
18+
builder.add( "spaceType", String.class );
19+
builder.add( "engine", String.class );
20+
builder.add( "parameters", OpenSearchVectorTypeMethod.Parameters.class );
21+
}
22+
23+
public static class ParametersJsonAdapterFactory
24+
extends
25+
AbstractConfiguredExtraPropertiesJsonAdapterFactory {
26+
@Override
27+
protected <T> void addFields(Builder<T> builder) {
28+
builder.add( "m", Integer.class );
29+
builder.add( "efConstruction", Integer.class );
30+
}
31+
}
32+
}

backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/lowlevel/index/mapping/impl/PropertyMapping.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public class PropertyMapping extends AbstractTypeMapping {
113113
* https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
114114
*/
115115
@SerializedName("index_options")
116-
private JsonElement indexOptions;
116+
private ElasticsearchDenseVectorIndexOptions indexOptions;
117117

118118
/*
119119
* k-NN vector datatype
@@ -125,7 +125,7 @@ public class PropertyMapping extends AbstractTypeMapping {
125125
* k-NN vector datatype
126126
* https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector/
127127
*/
128-
private JsonElement method;
128+
private OpenSearchVectorTypeMethod method;
129129

130130
/*
131131
* k-NN vector datatype
@@ -247,11 +247,11 @@ public void setSimilarity(String similarity) {
247247
this.similarity = similarity;
248248
}
249249

250-
public JsonElement getIndexOptions() {
250+
public ElasticsearchDenseVectorIndexOptions getIndexOptions() {
251251
return indexOptions;
252252
}
253253

254-
public void setIndexOptions(JsonElement indexOptions) {
254+
public void setIndexOptions(ElasticsearchDenseVectorIndexOptions indexOptions) {
255255
this.indexOptions = indexOptions;
256256
}
257257

@@ -263,11 +263,11 @@ public void setDimension(Integer dimension) {
263263
this.dimension = dimension;
264264
}
265265

266-
public JsonElement getMethod() {
266+
public OpenSearchVectorTypeMethod getMethod() {
267267
return method;
268268
}
269269

270-
public void setMethod(JsonElement method) {
270+
public void setMethod(OpenSearchVectorTypeMethod method) {
271271
this.method = method;
272272
}
273273

backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/lowlevel/index/mapping/impl/PropertyMappingJsonAdapterFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ protected <T> void addFields(Builder<T> builder) {
2727
builder.add( "elementType", String.class );
2828
builder.add( "dims", Integer.class );
2929
builder.add( "similarity", String.class );
30-
builder.add( "indexOptions", JsonElement.class );
30+
builder.add( "indexOptions", ElasticsearchDenseVectorIndexOptions.class );
3131
builder.add( "dimension", Integer.class );
32-
builder.add( "method", JsonElement.class );
32+
builder.add( "method", OpenSearchVectorTypeMethod.class );
3333
builder.add( "dataType", String.class );
3434
}
3535
}

backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/types/mapping/impl/Elasticsearch8VectorFieldTypeMappingContributor.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
package org.hibernate.search.backend.elasticsearch.types.mapping.impl;
88

99
import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.DataTypes;
10+
import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.ElasticsearchDenseVectorIndexOptions;
1011
import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMapping;
1112
import org.hibernate.search.backend.elasticsearch.search.predicate.impl.ElasticsearchKnnPredicate;
1213
import org.hibernate.search.backend.elasticsearch.types.impl.ElasticsearchIndexValueFieldType;
1314
import org.hibernate.search.engine.backend.types.VectorSimilarity;
1415
import org.hibernate.search.engine.search.predicate.spi.PredicateTypeKeys;
1516
import org.hibernate.search.util.common.AssertionFailure;
1617

17-
import com.google.gson.JsonObject;
18-
1918
public class Elasticsearch8VectorFieldTypeMappingContributor implements ElasticsearchVectorFieldTypeMappingContributor {
2019
@Override
2120
public void contribute(PropertyMapping mapping, Context context) {
@@ -27,13 +26,13 @@ public void contribute(PropertyMapping mapping, Context context) {
2726
mapping.setSimilarity( resolvedVectorSimilarity );
2827
}
2928
if ( context.maxConnections() != null || context.beamWidth() != null ) {
30-
JsonObject indexOptions = new JsonObject();
31-
indexOptions.addProperty( "type", "hnsw" );
29+
ElasticsearchDenseVectorIndexOptions indexOptions = new ElasticsearchDenseVectorIndexOptions();
30+
indexOptions.setType( "hnsw" );
3231
if ( context.maxConnections() != null ) {
33-
indexOptions.addProperty( "m", context.maxConnections() );
32+
indexOptions.setM( context.maxConnections() );
3433
}
3534
if ( context.beamWidth() != null ) {
36-
indexOptions.addProperty( "ef_construction", context.beamWidth() );
35+
indexOptions.setEfConstruction( context.beamWidth() );
3736
}
3837
mapping.setIndexOptions( indexOptions );
3938
}

0 commit comments

Comments
 (0)