在上篇《weaviate向量库从零开始——weaviate集合、对象管理从零代码开始详解》我们讲解了weaviate数据库对数据对象的相关操作,但是其相关检索操作并没有相关向量化数据的检索。只有我们启用了相关向量化模型才会对数据对象做向量化并生成相对的向量数据以作语义检索相关的操作。其他相关配置信息请参考上篇文章。
pom:
<dependency><groupId>io.weaviate</groupId><artifactId>client</artifactId><version>4.7.0</version> <!-- Check latest version --></dependency>
1.创建带向量化的集合
本地搭建weaviate并选择向量化器的时候可参考以下的代码,其中向量化模型需要自己搭建,如OpenAI-Text-Embeddings等。
public void createCollWithVector((WeaviateClient client) {// 向量化器配置Map<String, Object> text2vecOpenAI = new HashMap<>();Map<String, Object> text2vecOpenAISettings = new HashMap<>();text2vecOpenAISettings.put("properties", new String[]{ "name" });text2vecOpenAI.put("text2vec-openai", text2vecOpenAISettings);Map<String, Object> text2vecCohere = new HashMap<>();Map<String, Object> text2vecCohereSettings = new HashMap<>();text2vecCohereSettings.put("properties", new String[]{ "body" });text2vecCohere.put("text2vec-cohere", text2vecCohereSettings);// 定义向量配置Map<String, WeaviateClass.VectorConfig> vectorConfig = new HashMap<>();vectorConfig.put("name_vector", WeaviateClass.VectorConfig.builder().vectorIndexType("hnsw").vectorizer(text2vecOpenAI).build());vectorConfig.put("body_vector", WeaviateClass.VectorConfig.builder().vectorIndexType("hnsw").vectorizer(text2vecCohere).build());// 在WeaviateClass Builder中定义矢量器WeaviateClass articleClass = WeaviateClass.builder().className(className).properties(Arrays.asList(titleProperty, bodyProperty)).vectorConfig(vectorConfig).build();// 创建集合Result<Boolean> result = client.schema().classCreator().withClass(articleClass).run();
}
2.weaviate cloud向量化实例
2.1.创建Client
java客户端尚未得到官方支持,实例化时手动传递X-Weaviate-Api-Key
和X-Weaviate-Cluster-Url
标头才能使用向量化器:
public void createClient() {String scheme = "https";String weaviateUrl = "uvujcdtvtiwvjdnaavdt6q.c0.asia-southeast1.gcp.weaviate.cloud";String weaviateKey = "Y4kK0TrhOl3mzewXyfpd6gtebEryzBfJWRyJ";Map<String, String> headers = new HashMap<String, String>() { {put("X-Weaviate-Api-Key", weaviateKey);put("X-Weaviate-Cluster-Url", "https://" + weaviateUrl);} };Config config = new Config(scheme, weaviateUrl, headers);try {WeaviateClient client = WeaviateAuthClient.apiKey(config, weaviateKey);} catch (AuthException e) {e.printStackTrace();}
}
2.2.创建带向量化器的集合
我们本此主要是在weaviate cloud上使用,选择的向量化器也是weaviate cloud自带的Weaviate-Text-Embeddings向量化模型(Snowflake/snowflake-arctic-embed-l-v2.0
)。
Snowflake/snowflake-arctic-embed-m-v1.5
最适合主要为英语且文本长度通常在 512 个tokens以下的数据集。Snowflake/snowflake-arctic-embed-l-v2.0
非常适合包含多种语言或需要**更长上下文(最多 8192 个tokens)**的数据集。该模型针对英语和多语言检索任务进行了优化,性能强劲。
public void createCollWithVector(WeaviateClient client, String className) {Map<String, Object> text2vecWeaviate = new HashMap<>();Map<String, Object> text2vecWeaviateSettings = new HashMap<>();text2vecWeaviateSettings.put("properties", new String[]{"title"});text2vecWeaviateSettings.put("model", new String[]{"Snowflake/snowflake-arctic-embed-l-v2.0"});text2vecWeaviateSettings.put("dimensions", new Integer[]{1024}); // 1024, 256text2vecWeaviateSettings.put("base_url", new String[]{"<custom_weaviate_url>"});text2vecWeaviate.put("text2vec-weaviate", text2vecWeaviateSettings);// 定义向量配置Map<String, WeaviateClass.VectorConfig> vectorConfig = new HashMap<>();vectorConfig.put("title_vector", WeaviateClass.VectorConfig.builder().vectorIndexType("hnsw").vectorizer(text2vecWeaviate).build());// 创建集合WeaviateClass clazz = WeaviateClass.builder().className(className).vectorConfig(vectorConfig).build();Result<Boolean> result = client.schema().classCreator().withClass(clazz).run();System.out.println("创建带有向量化器的集合结果:" + result.getResult());}
model
(可选):用于嵌入生成的模型的名称。dimensions
(可选):用于生成嵌入的维数。base_url
(可选):Weaviate 嵌入服务的基本 URL。(大多数情况下不需要。)
2.3.添加数据对象
public void ImportObject(WeaviateClient client, String className) {var map1 = Map.of("title", "刘亦菲", "description", "刘亦菲是2000年出生的女演员,2005年9月14日,刘亦菲在《如果爱》中饰演“孙纳”,获得金马奖、金像奖最佳女主角。");var map2 = Map.of("title", "杨幂", "description", "杨幂是85后花旦中的顶流代表,出生日期:1986年9月12日;出生地:北京市;代表奖项:上海电视节白玉兰奖提名、休斯顿国际电影节最佳女主角;以高产量和高话题度闻名。");var sourceObjects = List.of(map1, map2);List<HashMap<String, Object>> objects = new ArrayList<>();for (Map<String, String> sourceObject : sourceObjects) {HashMap<String, Object> schema = new HashMap<>();schema.put("title", sourceObject.get("title"));schema.put("description", sourceObject.get("description"));objects.add(schema);}// 批量写入ObjectsBatcher batcher = client.batch().objectsBatcher();for (Map<String, Object> properties : objects) {batcher.withObject(WeaviateObject.builder().className(className).properties(properties)// .tenant("tenantA") // 如果启用了多租户,请指定要添加对象的租户。.build());}// Flushbatcher.run();}
2.4.查询数据对象
public void readObject(WeaviateClient client, String className) {Result<List<WeaviateObject>> result = client.data().objectsGetter().withClassName(className)
// .withID(id).withVector().run();System.out.println(result.getResult());}
2.5.向量搜索(语义检索)
public void queryData(WeaviateClient client, String className) {Fields returnFields = Fields.builder().fields(new Field[]{Field.builder().name("description").build(),}).build();NearTextArgument nearText = NearTextArgument.builder().concepts(new String[]{"出生地"}).build();String nearTextQuery = GetBuilder.builder().className("DemoCollection").fields(returnFields).withNearTextFilter(nearText).limit(2).build().buildQuery();Result<GraphQLResponse> nearTextResult = client.graphQL().raw().withQuery(nearTextQuery).run();if (nearTextResult.hasErrors()) {System.err.println(nearTextResult.getError());} else {System.out.println("向量检索结果: " + nearTextResult.getResult().getData());}}
2.6.实例执行
createCollWithVector(client, "DemoCollection");
ImportObject(client, "DemoCollection");
readObject(client, "DemoCollection");
queryData(client, "DemoCollection");
readObject()
查询结果:
[WeaviateObject(id=3c367697-5873-4ad2-be1e-e2f5c2ad9e1a, className=DemoCollection, creationTimeUnix=1747038079383, lastUpdateTimeUnix=1747038079383, properties={description=杨幂是85后花旦中的顶流代表,出生日期:1986年9月12日;出生地:北京市;代表奖项:上海电视节白玉兰奖提名、休斯顿国际电影节最佳女主角;以高产量和高话题度闻名。, title=杨幂}, additional=null, vector=null, vectors={title_vector=[Ljava.lang.Float;@59e32960}, vectorWeights=null, tenant=null), WeaviateObject(id=965aceb5-5ae9-4c60-a2ea-b93d0ac96736, className=DemoCollection, creationTimeUnix=1747038079383, lastUpdateTimeUnix=1747038079383, properties={description=刘亦菲是2000年出生的女演员,2005年9月14日,刘亦菲在《如果爱》中饰演“孙纳”,获得金马奖、金像奖最佳女主角。, title=刘亦菲}, additional=null, vector=null,
vectors={title_vector=[Ljava.lang.Float;@7c214cc0}, vectorWeights=null, tenant=null)
]
可以明显看出向量数据已经生成。
queryData()
执行结果:
向量检索结果: {Get={DemoCollection=[{description=刘亦菲是2000年出生的女演员,2005年9月14日,刘亦菲在《如果爱》中饰演“孙纳”,获得金马奖、金像奖最佳女主角。}, {description=杨幂是85后花旦中的顶流代表,出生日期:1986年9月12日;出生地:北京市;代表奖项:上海电视节白玉兰奖提名、休斯顿国际电影节最佳女主角;以高产量和高话题度闻名。}]}}