我们项目中选择使用ES做向量数据库,方便后面我们基于ES做混合检索。这一篇介绍下如何在LangChain4J中接入ES。
增加依赖
首先,langchain4j-elasticsearch是一个针对langchain4j的es的包, 里面提供了一些相关的API可以使用。
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-elasticsearch</artifactId>
<version>1.11.0-beta19</version>
</dependency>
langchain4j-elasticsearch 模块提供了与 Elasticsearch 的集成,将其作为嵌入存储和内容检索器使用。 它主要包含两个类: - ElasticsearchEmbeddingStore:EmbeddingStore 接口的实现,使用 Elasticsearch 来存储和检索嵌入向量。 - ElasticsearchContentRetriever:ContentRetriever 接口的实现,使用 Elasticsearch 基于向量相似度搜索来检索相关文档。
ES部署
按照这篇文档中的方式,先把ES安装上:
✅使用ElasticSearch做关键词检索
为了做混合检索,我们需要部署es,并给ES安装上IK中文分词器(因为我们主要文档都是中文场景),用于后续我们的关键词检索。 ES docker启动:(请使用8.19.10版本,以文档为准,最开始用的7.x的版本,但是后面有兼容性问题(7.x LLMentor
定义ElasticsearchEmbeddingStore
@Configuration
@EnableConfigurationProperties
public
}
有了这个ElasticsearchEmbeddingStore之后,我们就可以把向量化以后的chunk保存在es中了。
定义Embedding模型
有两向量存储了之后,我们还需要有一个向量模型,先把我们的Segment转成embedding,那么我们同样在刚刚的ElasticSearchConfiguration中定义一个EmbeddingModel
@Autowired
private
@Bean
public
}
这里需要用到几个参数: - modelName:embedding模型的名称 - dimensions:向量的维度 - baseUrl:模型的baseurl 我们通过配置文件写入:
elasticsearch:
host: http://xx.xx.xx.xx:9200
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
model-name: text-embedding-v4
api-key: @dashscope.api.key@
dimensions: 1536
对应的ElasticSearchProperties定义如下:
@ConfigurationProperties
public
}
这样,我们就有了embeddingModel和embeddingStore了。就可以做嵌入和存储了。
@RestController
@RequestMapping
public
embeddingStore
embeddingStore
}
运行结果:
0.8060765
I like football.
通过http://xx.xx.xx.xx:9200/know-engine/_mapping 能查看索引的定义: 有三个字段:metadata、text、vector
{
}
- vector (向量字段) 这是该配置中最关键的部分,用于 AI 语义搜索。 - type: dense_vector:表示存储的是稠密向量数据。 - dims: 1536:向量的维度是 1536。 - similarity: cosine:使用余弦相似度来计算向量之间的距离。 - index_options (索引算法): - type: int8_hnsw:使用了 HNSW 算法进行近似搜索,并且使用了 int8 量化。量化可以显著减少内存占用并提高搜索速度,同时保持较高的精度。 - m: 16:HNSW 图中每个节点的邻居数量。 - ef_construction: 添加一个节点时查找的最相邻doc构建邻居,默认为100。
- text (文本字段) - type: text:用于存储实际的文本内容。 - fields.keyword:同时包含一个 keyword 子字段。这意味着该字段既支持全文检索(分词),也支持精确匹配(如排序或聚合)。
- metadata (元数据字段) - 这是一个对象类型,目前包含一个 version 字段,用于记录数据的版本信息。