diff --git a/pom.xml b/pom.xml
index 9b5d91ec631428899476c58254f5a16c49e9329a..0e9142ba08ee9cd29daf6b09d5be7b00604092da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -174,7 +174,7 @@
org.dromara
milvus-plus-boot-starter
- 2.1.0
+ 2.1.4
org.apache.commons
@@ -210,6 +210,19 @@
+
+
+
+
+
+
+
+ redis.clients
+ jedis
+ 5.2.0-beta5
+
+
+
diff --git a/src/main/java/com/github/javpower/javavision/util/redis/vector/DistanceMetric.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/DistanceMetric.java
new file mode 100644
index 0000000000000000000000000000000000000000..2552528b4b7390d8fa5b50f4c45b3c22ae87a950
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/DistanceMetric.java
@@ -0,0 +1,7 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+public enum DistanceMetric {
+ COSINE,
+ L2,
+ IP
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldSchema.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldSchema.java
new file mode 100644
index 0000000000000000000000000000000000000000..dee22199bf2d9bda089787229a2632f3df991abc
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldSchema.java
@@ -0,0 +1,21 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+import lombok.Data;
+
+@Data
+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;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldType.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldType.java
new file mode 100644
index 0000000000000000000000000000000000000000..44936b488cbdbbcf2e8f4bbcac37d705ffe2cdbc
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/FieldType.java
@@ -0,0 +1,7 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+public enum FieldType {
+ TEXT,
+ VECTOR,
+ NUMBER
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorTest.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c50f195b32b184b6609eb4e071e9dc11cc9487c
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorTest.java
@@ -0,0 +1,39 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+import cn.hutool.json.JSONUtil;
+import org.springframework.web.bind.annotation.RestController;
+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;
+
+@RestController
+public class RedisVectorTest {
+
+
+ public static void main(String[] args) {
+ UnifiedJedis unifiedjedis=new UnifiedJedis(new HostAndPort("xxxxx",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)
+ );
+ // 创建一个名为 "myIndex" 的向量索引
+ redisVectorTool.createVectorIndex("testIndex3", 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("testIndex3", "1", document); // 假设文档ID为 "1"
+ // 执行向量搜索,假设我们搜索与上面添加的向量相似的文档
+ float[] queryVector = new float[]{0.1f, 0.2f, 0.3f, 0.4f};
+ List searchResults = redisVectorTool.searchVector("testIndex3", queryVector, 10); // 限制返回结果为10个
+ // 打印搜索结果
+ searchResults.forEach(v-> System.out.println(JSONUtil.toJsonStr(v)));
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorUtil.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0cdc02e6fbfdadd1030651414dd0ab25e57cefc
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/RedisVectorUtil.java
@@ -0,0 +1,64 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+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;
+
+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/src/main/java/com/github/javpower/javavision/util/redis/vector/VectorDataType.java b/src/main/java/com/github/javpower/javavision/util/redis/vector/VectorDataType.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2e5b6111866b18e2548dd02d757c516ecb6b547
--- /dev/null
+++ b/src/main/java/com/github/javpower/javavision/util/redis/vector/VectorDataType.java
@@ -0,0 +1,7 @@
+package com.github.javpower.javavision.util.redis.vector;
+
+// 定义向量数据类型的枚举
+public enum VectorDataType {
+ FLOAT32,
+ FLOAT64
+}
\ No newline at end of file