# 引言
Elasticsearch 是一个分布式的RESTful搜索和分析引擎,提供多租户的全文搜索引擎功能,同时支持HTTP接口和无模式的JSON文档。它不仅能够进行关键词搜索,还支持向量搜索、混合搜索和复杂过滤等功能。而 `ElasticsearchRetriever` 是一个通用的包装类,通过Query DSL提供对所有Elasticsearch功能的灵活访问。本文旨在帮助您起步使用ElasticsearchRetriever,并提供详细的代码示例和常见问题的解决方案。
# 主要内容
## 集成详情
`ElasticsearchRetriever` 支持自托管和云服务两种方式进行部署,相关包名为 `langchain_elasticsearch`。
## 安装与设置
您可以通过以下命令安装必须的库:
```bash
%pip install -qU langchain-community langchain-elasticsearch
接下来设置您的Elasticsearch实例,可以选择本地安装或使用Elastic Cloud。
本地安装
使用官方的Elasticsearch Docker镜像进行本地安装,详情请参考 Elasticsearch Docker documentation。
Elastic Cloud
注册Elastic Cloud并开启免费试用,可以获得一个无需登录就能访问的Elasticsearch实例。
from elasticsearch import Elasticsearch
es_url = "http://localhost:9200" # 使用API代理服务提高访问稳定性
es_client = Elasticsearch(hosts=[es_url])
es_client.info()
配置示例数据
设置向量搜索所需的嵌入:
from langchain_community.embeddings import DeterministicFakeEmbedding
embeddings = DeterministicFakeEmbedding(size=3)
定义测试数据:
texts = ["foo", "bar", "world", "hello world", "hello", "foo bar", "bla bla foo"]
index_name = "test-langchain-retriever"
数据索引
创建一个索引并插入数据:
from elasticsearch.helpers import bulk
from typing import Iterable, Dict
def create_index(es_client: Elasticsearch, index_name: str, text_field: str, dense_vector_field: str, num_characters_field: str):
es_client.indices.create(
index=index_name,
mappings={
"properties": {
text_field: {"type": "text"},
dense_vector_field: {"type": "dense_vector"},
num_characters_field: {"type": "integer"},
}
},
)
def index_data(es_client: Elasticsearch, index_name: str, text_field: str, dense_vector_field: str, embeddings: Embeddings, texts: Iterable[str], refresh: bool = True) -> None:
create_index(es_client, index_name, text_field, dense_vector_field, num_characters_field)
vectors = embeddings.embed_documents(list(texts))
requests = [
{
"_op_type": "index",
"_index": index_name,
"_id": i,
text_field: text,
dense_vector_field: vector,
num_characters_field: len(text),
}
for i, (text, vector) in enumerate(zip(texts, vectors))
]
bulk(es_client, requests)
if refresh:
es_client.indices.refresh(index=index_name)
查询示例
向量搜索
使用伪嵌入进行向量搜索:
def vector_query(search_query: str) -> Dict:
vector = embeddings.embed_query(search_query)
return {
"knn": {
"field": dense_vector_field,
"query_vector": vector,
"k": 5,
"num_candidates": 10,
}
}
实例化向量检索器并查询:
from langchain_elasticsearch import ElasticsearchRetriever
vector_retriever = ElasticsearchRetriever.from_es_params(
index_name=index_name,
body_func=vector_query,
content_field=text_field,
url=es_url,
)
vector_retriever.invoke("foo")
混合搜索
结合向量搜索和BM25搜索:
def hybrid_query(search_query: str) -> Dict:
vector = embeddings.embed_query(search_query)
return {
"query": {
"match": {
text_field: search_query,
},
},
"knn": {
"field": dense_vector_field,
"query_vector": vector,
"k": 5,
"num_candidates": 10,
},
"rank": {"rrf": {}},
}
hybrid_retriever = ElasticsearchRetriever.from_es_params(
index_name=index_name,
body_func=hybrid_query,
content_field=text_field,
url=es_url,
)
hybrid_retriever.invoke("foo")
常见问题和解决方案
- 连接错误:确保Elasticsearch实例正在运行并且端点正确配置。如果您在某些地区遇到访问问题,考虑使用API代理服务。
- 搜索结果不准确:检查您的查询DSL是否正确配置,尤其是在复杂查询中。
总结和进一步学习资源
ElasticsearchRetriever 提供了一种灵活而强大的方式来利用Elasticsearch的高级搜索功能。通过本文,您学习到了如何进行向量搜索、BM25搜索、混合搜索和复杂过滤。如果您想更深入地了解,还可以参考以下资源:
参考资料
- Elasticsearch官方文档: www.elastic.co/guide/index…
- Langchain-ElasticSearch GitHub Repository
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---