diff --git a/agents-flex-store/agents-flex-store-redis/pom.xml b/agents-flex-store/agents-flex-store-redis/pom.xml index 764ca41ca8e68ae8f0ea5321b5dcaad0d3d3ee3e..f3a5624d6953a83e1437beddfb564c344d310746 100644 --- a/agents-flex-store/agents-flex-store-redis/pom.xml +++ b/agents-flex-store/agents-flex-store-redis/pom.xml @@ -16,5 +16,18 @@ 8 UTF-8 + + + com.agentsflex + agents-flex-core + 1.0.0-beta.9 + compile + + + redis.clients + jedis + 5.2.0-beta5 + + diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Main.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Main.java deleted file mode 100644 index d9109c587109f3d1dadbd539cca4f462904638f3..0000000000000000000000000000000000000000 --- a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.agentsflex; - -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Test.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Test.java new file mode 100644 index 0000000000000000000000000000000000000000..76a6980cfe98055e91b4c4810fe6049750e82915 --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/Test.java @@ -0,0 +1,39 @@ +package com.agentsflex; + +import com.agentsflex.store.redis.entity.DistanceMetric; +import com.agentsflex.store.redis.entity.FieldSchema; +import com.agentsflex.store.redis.entity.FieldType; +import com.agentsflex.store.redis.entity.VectorDataType; +import com.agentsflex.store.redis.util.RedisVectorUtil; +import com.alibaba.fastjson.JSON; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.UnifiedJedis; +import redis.clients.jedis.search.Document; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class Test { + public static void main(String[] args) { + UnifiedJedis unifiedjedis=new UnifiedJedis(new HostAndPort("xxxxxx",6379)); + RedisVectorUtil redisVectorTool=new RedisVectorUtil(unifiedjedis); + // 定义字段结构来创建索引 + List fields = Arrays.asList( + new FieldSchema("text", FieldType.TEXT, null, null, null), + new FieldSchema("vector", FieldType.VECTOR, VectorDataType.FLOAT32, 4, DistanceMetric.COSINE) + ); + // 创建一个名为 "redis-vector" 的向量索引 + redisVectorTool.createVectorIndex("redis-vector", fields); + // 添加一个文档到索引,包含文本和向量 + java.util.Map document = new HashMap<>(); + document.put("text", "This is a sample text"); + document.put("vector", new float[]{0.1f, 0.2f, 0.3f, 0.4f});// 示例向量数据 + redisVectorTool.addDocumentToIndex("redis-vector", "1", document); // 假设文档ID为 "1" + // 执行向量搜索,假设我们搜索与上面添加的向量相似的文档 + float[] queryVector = new float[]{0.1f, 0.2f, 0.3f, 0.4f}; + List searchResults = redisVectorTool.searchVector("redis-vector", queryVector, 10); // 限制返回结果为10个 + // 打印搜索结果 + searchResults.forEach(v-> System.out.println(JSON.toJSONString(v))); + } +} diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/DistanceMetric.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/DistanceMetric.java new file mode 100644 index 0000000000000000000000000000000000000000..b4b19d63dd26ed167757c248f613d8df3ab14022 --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/DistanceMetric.java @@ -0,0 +1,7 @@ +package com.agentsflex.store.redis.entity; + +public enum DistanceMetric { + COSINE, + L2, + IP +} diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldSchema.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldSchema.java new file mode 100644 index 0000000000000000000000000000000000000000..5e059c8f19a0c1bf8adc79f5af0504920bf3dad4 --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldSchema.java @@ -0,0 +1,58 @@ +package com.agentsflex.store.redis.entity; + + +public class FieldSchema { + private String name; + private FieldType type; + private VectorDataType dataType; + private Integer dimension; + private DistanceMetric metric; + + public FieldSchema(String name, FieldType type, VectorDataType dataType, Integer dimension, DistanceMetric metric) { + this.name = name; + this.type = type; + this.dataType = dataType; + this.dimension = dimension; + this.metric = metric; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public FieldType getType() { + return type; + } + + public void setType(FieldType type) { + this.type = type; + } + + public VectorDataType getDataType() { + return dataType; + } + + public void setDataType(VectorDataType dataType) { + this.dataType = dataType; + } + + public Integer getDimension() { + return dimension; + } + + public void setDimension(Integer dimension) { + this.dimension = dimension; + } + + public DistanceMetric getMetric() { + return metric; + } + + public void setMetric(DistanceMetric metric) { + this.metric = metric; + } +} diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldType.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldType.java new file mode 100644 index 0000000000000000000000000000000000000000..8fe9dc884381c89165712f971807ce1159805ded --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/FieldType.java @@ -0,0 +1,7 @@ +package com.agentsflex.store.redis.entity; + +public enum FieldType { + TEXT, + VECTOR, + NUMBER +} diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/VectorDataType.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/VectorDataType.java new file mode 100644 index 0000000000000000000000000000000000000000..0186ff5170be9822dea140087a3cdc8dbfec7161 --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/entity/VectorDataType.java @@ -0,0 +1,7 @@ +package com.agentsflex.store.redis.entity; + +// 定义向量数据类型的枚举 +public enum VectorDataType { + FLOAT32, + FLOAT64 +} diff --git a/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/util/RedisVectorUtil.java b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/util/RedisVectorUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..c3535b859298c0a20183f57d4775c07bc5c4a723 --- /dev/null +++ b/agents-flex-store/agents-flex-store-redis/src/main/java/com/agentsflex/store/redis/util/RedisVectorUtil.java @@ -0,0 +1,69 @@ +package com.agentsflex.store.redis.util; + +import com.agentsflex.store.redis.entity.FieldSchema; +import redis.clients.jedis.UnifiedJedis; +import redis.clients.jedis.search.*; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * xgc + * redis向量工具类 + */ +public class RedisVectorUtil { + + private UnifiedJedis unifiedjedis; + + public RedisVectorUtil(UnifiedJedis unifiedjedis){ + this.unifiedjedis=unifiedjedis; + } + public void createVectorIndex(String indexName, List fields) { + String pre= "doc:"+indexName+":"; + IndexDefinition definition = new IndexDefinition().setPrefixes(new String[]{pre}); + Schema schema = new Schema(); + for (FieldSchema field : fields) { + switch (field.getType()){ + case VECTOR: + Map attr = new HashMap<>(); + attr.put("TYPE", field.getDataType().name()); + attr.put("DIM", field.getDimension()); + attr.put("DISTANCE_METRIC", field.getMetric().name()); + schema.addHNSWVectorField(field.getName(),attr); + break; + case TEXT: + schema.addTextField(field.getName(),1); + break; + case NUMBER: + schema.addNumericField(field.getName()); + break; + } + } + unifiedjedis.ftCreate(indexName, IndexOptions.defaultOptions().setDefinition(definition), schema); + } + + public List searchVector(String indexName, float[] queryVector, int limit) { + // 创建查询向量 + byte[] vectorBytes = new byte[queryVector.length * 4]; + ByteBuffer byteBuffer = ByteBuffer.wrap(vectorBytes); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + for (float v : queryVector) { + byteBuffer.putFloat(v); + } + // 构建查询 + Query query = new Query("*=>[KNN " + limit + " @vector $vector AS score]").addParam("vector", vectorBytes).limit(0,limit).dialect(2); + // 执行搜索 + SearchResult results = unifiedjedis.ftSearch(indexName, query); + // 提取文档 + return results.getDocuments(); + } + + // 向索引中添加文档 + public void addDocumentToIndex(String indexName, String docId, Map fields) { + String key= "doc:"+indexName+":"+docId; + unifiedjedis.hsetObject(key,fields); + } +} diff --git a/agents-flex-test/pom.xml b/agents-flex-test/pom.xml index e7b1026f1c0d48e9b0314530cb51654bab08971d..303e60bd7576458a87b31712001ff2b0c10bf6f8 100644 --- a/agents-flex-test/pom.xml +++ b/agents-flex-test/pom.xml @@ -30,6 +30,11 @@ ${spring-boot.version} test + + com.agentsflex + agents-flex-store-milvus + 1.0.0-beta.1 +