Browse Source

Deprecate the _knn_search endpoint (#88828)

This change deprecates the kNN search API in favor of the new 'knn' option
inside the search API. The 'knn' option is now the preferred way of performing
kNN search.

Relates to #87625
Julie Tibshirani 3 years ago
parent
commit
21eb984e64

+ 13 - 0
docs/changelog/88828.yaml

@@ -0,0 +1,13 @@
+pr: 88828
+summary: Deprecate the `_knn_search` endpoint
+area: Vector Search
+type: deprecation
+issues: []
+deprecation:
+  title: Deprecate the `_knn_search` endpoint
+  area: REST API
+  details: -|
+    The kNN search API is deprecated in favor of the new 'knn' option
+    inside the search API. The 'knn' option is now the recommended way of running
+    ANN search.
+  impact: Users should switch from `_knn_search` to the search `knn` option.

+ 0 - 1
docs/reference/search.asciidoc

@@ -15,7 +15,6 @@ exception of the <<search-explain,explain API>>.
 * <<search-multi-search>>
 * <<async-search>>
 * <<point-in-time-api>>
-* <<knn-search-api>>
 * <<search-suggesters>>
 * <<search-terms-enum>>
 * <<scroll-api>>

+ 2 - 1
docs/reference/search/knn-search.asciidoc

@@ -4,8 +4,8 @@
 <titleabbrev>kNN search</titleabbrev>
 ++++
 
+deprecated::[8.4.0,"The kNN search API has been replaced by the <<<<search-api-knn, `knn` option>> in the search API."]
 experimental::[]
-
 Performs a k-nearest neighbor (kNN) search and returns the matching documents.
 
 ////
@@ -46,6 +46,7 @@ GET my-index/_knn_search
 }
 ----
 // TEST[continued]
+// TEST[warning:The kNN search API has been replaced by the `knn` option in the search API.]
 
 [[knn-search-api-request]]
 ==== {api-request-title}

+ 9 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/40_knn_search.yml

@@ -160,7 +160,11 @@ setup:
 
 ---
 "kNN search in _knn_search endpoint":
+  - skip:
+      features: ["allowed_warnings"]
   - do:
+      allowed_warnings:
+        - "The kNN search API has been replaced by the `knn` option in the search API."
       knn_search:
         index: test
         body:
@@ -182,7 +186,10 @@ setup:
   - skip:
       version: ' - 8.1.99'
       reason: 'kNN with filtering added in 8.2'
+      features: ["allowed_warnings"]
   - do:
+      allowed_warnings:
+        - "The kNN search API has been replaced by the `knn` option in the search API."
       knn_search:
         index: test
         body:
@@ -201,6 +208,8 @@ setup:
   - match: {hits.hits.0.fields.name.0: "rabbit.jpg"}
 
   - do:
+      allowed_warnings:
+        - "The kNN search API has been replaced by the `knn` option in the search API."
       knn_search:
         index: test
         body:

+ 2 - 7
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search.vectors/50_dense_vector_field_usage.yml

@@ -24,6 +24,7 @@ setup:
   - do:
       index:
         index: futest
+        id: "1"
         body:
           name: cow.jpg
           vector: [ 230.0, 300.33, -34.8988, 15.555, -200.0 ]
@@ -53,7 +54,7 @@ setup:
       version: ' - 8.0.99'
       reason: 'dense_vector field usage was added in 8.1'
   - do:
-      knn_search:
+      search:
         index: futest
         body:
           fields: [ "name" ]
@@ -63,12 +64,6 @@ setup:
             k: 2
             num_candidates: 3
 
-  - match: {hits.hits.0._id: "2"}
-  - match: {hits.hits.0.fields.name.0: "moose.jpg"}
-
-  - match: {hits.hits.1._id: "3"}
-  - match: {hits.hits.1.fields.name.0: "rabbit.jpg"}
-
   - do:
       indices.field_usage_stats: { index: futest }
 

+ 7 - 1
server/src/main/java/org/elasticsearch/rest/action/search/RestKnnSearchAction.java

@@ -10,6 +10,7 @@ package org.elasticsearch.rest.action.search;
 
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.client.internal.node.NodeClient;
+import org.elasticsearch.core.RestApiVersion;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.action.RestCancellableNodeClient;
@@ -28,11 +29,16 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
  */
 public class RestKnnSearchAction extends BaseRestHandler {
 
+    static final String DEPRECATION_MESSAGE = "The kNN search API has been replaced by the `knn` option in the search API.";
+
     public RestKnnSearchAction() {}
 
     @Override
     public List<Route> routes() {
-        return List.of(new Route(GET, "{index}/_knn_search"), new Route(POST, "{index}/_knn_search"));
+        return List.of(
+            Route.builder(GET, "{index}/_knn_search").deprecated(DEPRECATION_MESSAGE, RestApiVersion.V_8).build(),
+            Route.builder(POST, "{index}/_knn_search").deprecated(DEPRECATION_MESSAGE, RestApiVersion.V_8).build()
+        );
     }
 
     @Override

+ 39 - 0
server/src/test/java/org/elasticsearch/rest/action/search/RestKnnSearchActionTests.java

@@ -0,0 +1,39 @@
+/*
+ * 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.rest.action.search;
+
+import org.elasticsearch.core.RestApiVersion;
+import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.test.rest.FakeRestRequest;
+import org.elasticsearch.test.rest.RestActionTestCase;
+import org.junit.Before;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class RestKnnSearchActionTests extends RestActionTestCase {
+    private List<String> contentTypeHeader;
+    private RestKnnSearchAction action;
+
+    @Before
+    public void setUpAction() {
+        action = new RestKnnSearchAction();
+        controller().registerHandler(action);
+        contentTypeHeader = Collections.singletonList(randomCompatibleMediaType(RestApiVersion.V_8));
+    }
+
+    public void testDeprecation() {
+        RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withHeaders(
+            Map.of("Content-Type", contentTypeHeader, "Accept", contentTypeHeader)
+        ).withMethod(RestRequest.Method.GET).withPath("/some_index/_knn_search").build();
+
+        dispatchRequest(request);
+        assertCriticalWarnings(RestKnnSearchAction.DEPRECATION_MESSAGE);
+    }
+}