Skip to content

Commit

Permalink
Validate method parameters only after version 2_17_0
Browse files Browse the repository at this point in the history
k-NN introduced validation to prevent index creation api to accept
method paramters that are used by approximate k-NN search
algorithm. For ex: create index api accepts model_id, or,
method params even if knn index setting was not true before 2.17.

However, for index that were created before 2.17 and upgraded to 2.17,
will prevent cluster to parse those previously accepted index mapping.

Hence, k-NN will allow those paramters for indices that were created before 2.17,
but doesn't support those parameters starting 2.17.

Signed-off-by: Vijayan Balasubramanian <[email protected]>
  • Loading branch information
VijayanB committed Dec 2, 2024
1 parent 8d0edf4 commit 8da34f1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ public static class Builder extends ParametrizedFieldMapper.Builder {
@Setter
@Getter
private OriginalMappingParameters originalParameters;
@Setter
private boolean isKnnIndex;

public Builder(
String name,
Expand All @@ -207,6 +209,7 @@ public Builder(
this.indexCreatedVersion = indexCreatedVersion;
this.knnMethodConfigContext = knnMethodConfigContext;
this.originalParameters = originalParameters;
this.isKnnIndex = true;
}

@Override
Expand Down Expand Up @@ -262,7 +265,7 @@ public KNNVectorFieldMapper build(BuilderContext context) {
);
}

if (originalParameters.getResolvedKnnMethodContext() == null) {
if (originalParameters.getResolvedKnnMethodContext() == null || isKnnIndex == false) {
return FlatVectorFieldMapper.createFieldMapper(
buildFullName(context),
name,
Expand Down Expand Up @@ -374,10 +377,14 @@ public Mapper.Builder<?> parse(String name, Map<String, Object> node, ParserCont
String.format(Locale.ROOT, "Method and model can not be both specified in the mapping: %s", name)
);
}

// Check for flat configuration
if (isKNNDisabled(parserContext.getSettings())) {
validateFromFlat(builder);
builder.setKnnIndex(false);
if (parserContext.indexVersionCreated().onOrAfter(Version.V_2_17_0)) {
// on and after 2_17_0 we validate to makes sure that mapping doesn't contain parameters that are
// specific to approximate knn search algorithms
validateFromFlat(builder);
}
} else if (builder.modelId.get() != null) {
validateFromModel(builder);
} else {
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/org/opensearch/knn/index/OpenSearchIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -907,4 +907,27 @@ private List<KNNResult> getResults(final String indexName, final String fieldNam
return parseSearchResponse(searchResponseBody, fieldName);
}

public void testCreateNonKNNIndex_withKNNModelID() throws Exception {
Settings settings = Settings.builder().put(createKNNDefaultScriptScoreSettings()).build();
ResponseException ex = expectThrows(
ResponseException.class,
() -> createKnnIndex(INDEX_NAME, settings, createKnnIndexMapping(FIELD_NAME, "random-model-id"))
);
String expMessage = "Cannot set modelId or method parameters when index.knn setting is false";
assertThat(EntityUtils.toString(ex.getResponse().getEntity()), containsString(expMessage));
}

public void testCreateNonKNNIndex_withKNNMethodParams() throws Exception {
Settings settings = Settings.builder().put(createKNNDefaultScriptScoreSettings()).build();
ResponseException ex = expectThrows(
ResponseException.class,
() -> createKnnIndex(
INDEX_NAME,
settings,
createKnnIndexMapping(FIELD_NAME, 2, "hnsw", KNNEngine.FAISS.getName(), SpaceType.DEFAULT.getValue(), false)
)
);
String expMessage = "Cannot set modelId or method parameters when index.knn setting is false";
assertThat(EntityUtils.toString(ex.getResponse().getEntity()), containsString(expMessage));
}
}
16 changes: 16 additions & 0 deletions src/testFixtures/java/org/opensearch/knn/KNNRestTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,22 @@ protected String createKnnIndexMapping(final String fieldName, final Integer dim
.toString();
}

/**
* Utility to create a Knn Index Mapping with model id
*/
protected String createKnnIndexMapping(String fieldName, String modelId) throws IOException {
return XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject(fieldName)
.field("type", "knn_vector")
.field("model_id", modelId)
.endObject()
.endObject()
.endObject()
.toString();
}

/**
* Utility to create a Knn Index Mapping with specific algorithm and engine
*/
Expand Down

0 comments on commit 8da34f1

Please sign in to comment.