Облачная платформаAdvanced

Пример кода Java для векторного поиска

Язык статьи: Русский
Показать оригинал
Страница переведена автоматически и может содержать неточности. Рекомендуем сверяться с английской версией.

OpenSearch предоставляет стандартные REST APIs и клиенты, разработанные с использованием Java и Python.

В этом разделе представлен пример кода Java для создания векторных индексов, импорта и запросов векторных данных. Показано, как использовать клиент для реализации векторного поиска.

Требования

Добавьте следующую зависимость Maven в зависимости от фактической версии кластера. В этом примере используется OpenSearch 1.3.6.

// OpenSearch 2.19.0
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-high-level-client</artifactId>
<version>2.19.0</version>
</dependency>
// OpenSearch 1.3.6
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-high-level-client</artifactId>
<version>1.3.6</version>
</dependency>

Пример кода

пакет org.example;
импорт org.apache.http.HttpEntity;
импорт org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.opensearch.action.admin.indices.delete.DeleteIndexRequest;
import org.opensearch.action.admin.indices.refresh.RefreshRequest;
import org.opensearch.action.bulk.BulkRequest;
import org.opensearch.action.bulk.BulkResponse;
import org.opensearch.action.index.IndexRequest;
import org.opensearch.action.search.SearchResponse;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.client.Request;
import org.opensearch.client.RequestOptions;
import org.opensearch.client.Response;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientBuilder;
import org.opensearch.client.RestHighLevelClient;
import org.opensearch.client.indices.CreateIndexRequest;
import org.opensearch.client.indices.CreateIndexResponse;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.xcontent.DeprecationHandler;
import org.opensearch.common.xcontent.NamedXContentRegistry;
import org.opensearch.common.xcontent.XContentParser;
import org.opensearch.common.xcontent.XContentType;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.List;
public class ClientExampleOS {
private final RestHighLevelClient client;
public ClientExampleOS(RestHighLevelClient client) {
this.client = client;
}
//Создать клиент для доступа к неконфиденциальным кластерам.
public static RestHighLevelClient getClient(List<String> hosts, int port, String scheme) {
HttpHost[] httpHosts = hosts.stream().map(p -> new HttpHost(p, port, scheme)).toArray(HttpHost[]::new);
return new RestHighLevelClient(RestClient.builder(httpHosts));
}
//Создать клиент для доступа к кластеру безопасности.
public static RestHighLevelClient getClient(List<String> hosts, int port, String scheme, String пользователь, String пароль) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
HttpHost[] httpHosts = hosts.stream().map(p -> new HttpHost(p, port, scheme)).toArray(HttpHost[]::new);
final SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sc, NoopHostnameVerifier.INSTANCE);
RestClientBuilder builder = RestClient.builder(httpHosts).setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.disableAuthCaching();
httpClientBuilder.setSSLStrategy(sessionStrategy);
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
});
return new RestHighLevelClient(builder);
}
public static TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
# Create an index.
public void create(String index) throws IOException {
CreateIndexRequest request = new CreateIndexRequest(index);
request.settings(Settings.builder()
.put("index.vector", true) // Включить векторную функцию.
.put("index.number_of_shards", 1) //Установите количество шардов индекса по необходимости.
.put("index.number_of_replicas", 0) //Установите количество реплик индекса по необходимости.
);
String mapping =
"{" +
" \"properties\": {" +
" \"my_vector\": {" +
" \"type\": \"vector\", " + // Установите это поле как тип вектора.
" \"indexing\": \"true\"," + // Включите ускорение индекса.
" \"dimension\": \"2\"," + // Векторный индекс
" \"metric\": \"euclidean\"," + // Метрика схожести
" \"algorithm\": \"GRAPH\"" + // Алгоритм индекса
" }" +
" }" +
"}";
запрос.отображение(mapping, XContentType.JSON);
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
if (response.isAcknowledged()) {
System.out.println("create " + index + " success");
}
}
// Запишите данные. Рекомендуется держать размер пакета менее 500 векторов.
public void write(String индекс, Список<float[]> векторы) выбрасывает IOException {
BulkRequest запрос = new BulkRequest();
for (float[] vec : векторы) {
запрос.добавить(новый IndexRequest(индекс).источник("my_vector", вектор));
}
BulkResponse ответ = клиент.bulk(запрос, RequestOptions.DEFAULT);
if (response.hasFailures()) {
System.out.println(response.buildFailureMessage());
} else {
System.out.println("записать bulk в " + index + " успех");
}
// Необязательно. Elasticsearch будет обновлять его по умолчанию.
клиент.индексы().обновить(new RefreshRequest(index), RequestOptions.DEFAULT);
}
// Запрос векторов.
public void search(String index, float[] query, int size) throws IOException {
String queryFormat =
"{\n" +
" \"size\":%d,\n" +
" \"query\": {\n" +
" \"vector\": {\n" +
" \"my_vector\": {\n" + // Запрос названия поля вектора.
" \"vector\": %s,\n" +
" \"topk\":%d\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
String body = String.format(queryFormat, size, Arrays.toString(query), size);
Request request = new Request("POST", index + "/_search");
request.setJsonEntity(body);
Response response = client.getLowLevelClient().performRequest(request);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
System.out.println(response.getEntity()); //Обработать ошибку в соответствии с требованиями сервиса.
return;
}
// Обработайте обычно возвращаемый результат в соответствии с требованиями сервиса.
HttpEntity entity = response.getEntity();
XContentType xContentType = XContentType.fromMediaTypeOrFormat("application/json");
XContentParser parser = xContentType.xContent().createParser(NamedXContentRegistry.EMPTY,
DeprecationHandler.IGNORE_DEPRECATIONS, entity.getContent());
SearchResponse searchResponse = SearchResponse.fromXContent(parser);
System.out.println(searchResponse);
}
// Удалить индекс.
public void delete(String index) throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest(index);
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
if (response.isAcknowledged()) {
System.out.println("удалить " + index + " успешно");
}
}
public void close() throws IOException {
client.close();
}
public static void main(String[] args) throws IOException {
// Для кластера в режиме без безопасности выполните следующее:
RestHighLevelClient client = getClient(Arrays.asList("xx.xx.xx.xx"), 9200, "http");
/*
*Для кластера в режиме безопасности с включённым HTTPS выполните следующее:
* RestHighLevelClient client = getClient(Arrays.asList("xx.xx.xx.xx", "xx.xx.xx.xx"), 9200, "https", "user_name", "password");
*Для кластера в режиме безопасности с отключённым HTTPS выполните следующее:
* RestHighLevelClient client = getClient(Arrays.asList("xx.xx.xx.xx", "xx.xx.xx.xx"), 9200, "http", "user_name", "password");
*/
ClientExampleOS example = new ClientExampleOS(client);
String indexName = "my_index";
//Создать индекс.
пример.создать(indexName);
//Записать данные.
Список<float[]> данные = Массивы.asList(new float[]{1.0f, 1.0f}, new float[]{2.0f, 2.0f}, new float[]{3.0f, 3.0f});
example.write(indexName, данные);
//Запрос к индексу.
float[] queryVector = new float[]{1.0f, 1.0f};
пример.поиск(indexName, queryVector, 3);
//Удалить индекс.
example.delete(indexName);
//Закрыть клиент.
example.close();
}
}