Skip to content

Work with Valkey Search

Valkey-Search (BSD-3-Clause), provided as a Valkey module, is a high-performance Search engine optimized for AI-driven / Search / Analytics / Recommendation System related workloads.

Valkey GLIDE support Search as a built-in module API, allowing you to interact with Search module commands through dedicated client methods.

Before using a module, including the supported modules, it will need to be loaded into Valkey. See Modules Introduction on how to load modules into your Valkey service.

For more on version requirements, see our introduction on Modules API.

import static glide.api.models.GlideString.gs;
import glide.api.GlideClient;
import glide.api.models.configuration.GlideClientConfiguration;
import glide.api.models.configuration.NodeAddress;
import glide.api.commands.servermodules.FT;
import glide.api.models.GlideString;
import glide.api.models.commands.FT.FTCreateOptions;
import glide.api.models.commands.FT.FTCreateOptions.DataType;
import glide.api.models.commands.FT.FTCreateOptions.DistanceMetric;
import glide.api.models.commands.FT.FTCreateOptions.FieldInfo;
import glide.api.models.commands.FT.FTCreateOptions.VectorFieldHnsw;
import glide.api.models.commands.FT.FTSearchOptions;
import java.util.HashMap;
import java.util.Map;
// Both standalone and cluster mode are supported
GlideClientConfiguration config = GlideClientConfiguration.builder()
.address(NodeAddress.builder().host("localhost").port(6379).build())
.build();
GlideClient client = GlideClient.createClient(config).get();
// FT.CREATE a Hash index with vector fields
String prefix = "{hash}:";
String index = prefix + "index";
FieldInfo[] fields = new FieldInfo[] {
new FieldInfo("vec", "VEC", VectorFieldHnsw.builder(DistanceMetric.L2, 2).build())
};
FTCreateOptions options =
FTCreateOptions.builder().dataType(DataType.HASH).prefixes(new String[] {prefix}).build();
FT.create(client, index, fields, options).get(); // returns "OK"
// Insert hash data with vector fields (2-dimensional float32 vectors = 8 bytes each)
byte[] vec0 = new byte[] {
(byte) 0, (byte) 0, (byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0, (byte) 0
};
byte[] vec1 = new byte[] {
(byte) 0, (byte) 0, (byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0x80, (byte) 0xBF
};
Map<GlideString, GlideString> hash0 = new HashMap<>();
hash0.put(gs("vec"), gs(vec0));
client.hset(gs(prefix + "0"), hash0).get();
Map<GlideString, GlideString> hash1 = new HashMap<>();
hash1.put(gs("vec"), gs(vec1));
client.hset(gs(prefix + "1"), hash1).get();
Thread.sleep(1000); // let server digest the data and update index
// FT.SEARCH
byte[] queryVec = new byte[] {
(byte) 0, (byte) 0, (byte) 0, (byte) 0,
(byte) 0, (byte) 0, (byte) 0, (byte) 0
};
String query = "*=>[KNN 2 @VEC $query_vec]";
Map<GlideString, GlideString> params = new HashMap<>();
params.put(gs("query_vec"), gs(queryVec));
FTSearchOptions searchOptions =
FTSearchOptions.builder()
.params(params)
.build();
Object[] searchResponse = FT.search(client, index, query, searchOptions).get();
// searchResponse[0] == 2L
// searchResponse[1] contains a map with "{hash}:0" and "{hash}:1" vector search results

For more details on the Search module, see the Valkey Search topic.