ElasticSearch 你的本地向量数据库

我正参与‘掘金·启航计划’

ElasticSearch简介

Elasticsearch(opens in a new tab)是一个分布式、RESTful搜索和分析引擎。它提供了一个分布式、多租户能力的全文搜索引擎,具有HTTP网络接口和无模式JSON文档。之后我们将简称ElasticSearch为Es.

通常我们在项目中使用到的Es场景一般如淘宝搜索,百度搜索.这次我们将结合Langchain+OpenAI使Es成为你本地向量存储库.

ElasticSearch安装

请查看Elasticsearch安装说明(opens in a new tab)
Es的安装在本文中不再赘述,感兴趣的可以先去官网先LookLook,后期会针对Es在Mac以及Linux安装单独出一篇文章

开始

准备工作

本文基于python3.11展开、 Es版本为7.17.4

#首先我们安装一些必须的依赖
pip3 install elasticsearch
pip3 install openai
pip3 install langchain

话不多说上代码

请详细阅读代码注释

#引入环境变量
import os
#设置环境变量你的OpenAI秘钥用来之后实例化Embeddings
os.environ["OPENAI_API_KEY"] = "Your OpenAI key"
#设置Es地址用于之后LangChain链接Es
os.environ["ELASTICSEARCH_URL"] = "http://localhost:9200"
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import ElasticVectorSearch
#实例化一个OpenAIEmbedding用于为数据向量化操作
embeddings = OpenAIEmbeddings(openai_api_key=os.environ["OPENAI_API_KEY"])
# 链接一个Es实例,elasticsearch_url为Es的地址我这里是本地无密码的Es所以直接就是http://localhost:9200,index_name就是Es的索引名称
elastic_vector_search = ElasticVectorSearch(
    elasticsearch_url="http://localhost:9200",
    index_name="test3",
    embedding=embeddings
)
#引入文字加载器
from langchain.document_loaders import TextLoader
#引入文字分词器
from langchain.text_splitter import CharacterTextSplitter
#加载我们准备好的txt文档
loader = TextLoader('./public/school.txt')
documents = loader.load()
#使用分词器将我们的数据分割成一小段一小段的内容,separator指分隔符建议根据文本进行自定义,chunk_size指分割大小,偶尔他分隔的内容也会比你设置的大小要大
text_splitter = CharacterTextSplitter( separator = "<<===>>",
                                       chunk_size = 1000,
                                       chunk_overlap  = 20,
                                       length_function = len)
docs = text_splitter.split_documents(documents)
#将分隔好的document向量化持久化存储在Es中
res = elastic_vector_search.add_documents(docs)
#这里打印我们可以看到返回的Id串
print(res)

比如这样的结果
image.png
出现这个画面说明你已经成功将数据向量化并存储在Es中了
如果你之前使用过Es那么你已经可以在Es中查看到存储的向量数据了

搜索

q = "根据你提供的文档提问的问题"
#搜索到相关的docs,默认搜素4个片段
docs = elastic_vector_search.similarity_search(q)
#打印你可以看到具体搜索到了哪些文章片段
print(docs)
#将搜索到的docs转换为向量
vectordb = elastic_vector_search.from_documents(docs,embeddings)
retriever = vectordb.as_retriever()
#创建Chain机器人
chain = ConversationalRetrievalChain.from_llm(ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k-0613"),
                                              retriever=retriever,
                                              return_source_documents=True)
                                              
def get_answer(question):
    chat_history = []
    result = chain({"question": question, "chat_history": chat_history})
    return result["answer"]
#这时你就可以看到OpenAI输出的结果啦
print(get_answer(q))

总结

 不得不说LangChain是一个很牛的依赖,之前有讲过ChormDb作为本地向量数据库、其实Redis也可以作为本地向量数据库,之后将会单独出一篇文章进行讲解。其实所谓的本地向量数据库殊途同归原理都是一样的。就像Mysql和MongoDB一样,虽然一个是关系型数据库,一个是非关系型数据库,但他们核心都一样,甚至Sql语句也类似。好了,希望这篇文章能帮助你更好的理解向量数据库。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYehGZ9h' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片