在机关网站建设会上讲话,河源哪里做网站,南做网站,建设银行网站怎么看交易记录Elasticsearch 是一款功能强大的开源搜索引擎#xff0c;可用于全文搜索、分析和数据可视化。传统上#xff0c;Elasticsearch 以其执行基于关键字/词汇的搜索的能力而闻名#xff0c;其中文档基于精确或部分关键字匹配进行匹配。然而#xff0c;Elasticsearch 已经发展到支…
Elasticsearch 是一款功能强大的开源搜索引擎可用于全文搜索、分析和数据可视化。传统上Elasticsearch 以其执行基于关键字/词汇的搜索的能力而闻名其中文档基于精确或部分关键字匹配进行匹配。然而Elasticsearch 已经发展到支持语义搜索 —— 一种专注于理解单词和短语背后的含义而不仅仅是匹配关键字的方法。
Elasticsearch 中的语义搜索可实现更直观和上下文感知的搜索体验即使查询中没有精确的关键字也可以找到相关信息。本文将探讨如何在 Elasticsearch 中实现语义搜索、其优势和实际用例。 语义搜索
语义搜索是一种超越传统基于关键字的搜索的技术它考虑了搜索查询的上下文、意图和含义。与专注于文字匹配的关键字搜索不同语义搜索了解单词和概念之间的关系从而实现更准确、更相关的搜索结果。
例如在基于关键字的搜索中查询 “laptop battery life” 可能会返回包含这些确切单词的文档。但是语义搜索可能会返回讨论相关概念的文档例如 “long-lasting laptops”、“energy-efficient devices”甚至 “portable computers with extended battery life.”。 Elasticsearch 如何支持语义搜索
Elasticsearch 通过多种技术组合支持语义搜索包括
向量表示使用预训练模型如 BERT来自 Transformers 的双向编码器表示将文本转换为可捕获语义含义的密集向量嵌入。相似度评分测量查询向量和文档向量之间的相似度以根据语义相关性对搜索结果进行排名。自定义分析器创建自定义标记器、过滤器和分析器以增强语义理解的方式预处理文本数据。与机器学习模型集成利用与 Elasticsearch 集成的机器学习模型执行实体识别、情感分析等任务 架构 —— 使用 Elasticsearch 进行语义搜索 Elasticsearch 中两个非常重要的概念是文档和索引。 文档
文档是字段及其相关值的集合。每个文档都是一个 JSON 对象其中包含结构化格式的数据。例如代表一本书的文档可能包含标题、作者和出版日期等字段。 索引
索引是文档的集合以高度优化的格式存储旨在执行高效搜索。索引类似于关系数据库中的表但它们更灵活可以存储复杂的数据结构。
要使用 Elasticsearch你需要将数据组织成文档然后将所有文档添加到索引中。这使 Elasticsearch 能够根据搜索查询高效地搜索和检索相关文档。 在 Elasticsearch 中实现语义搜索 1. 设置 Elasticsearch
首先确保你已启动并运行 Elasticsearch。你可以通过启动 Elasticsearch 的 Docker 容器来远程连接到 elasticsearch
docker run -it \--rm \--name elasticsearch \-p 9200:9200 \-p 9300:9300 \-e discovery.typesingle-node \-e xpack.security.enabledfalse \docker.elastic.co/elasticsearch/elasticsearch:8.4.3 2. 数据加载和预处理
在此步骤中我们将加载 documents.json 文件并对其进行预处理以使层次结构扁平化使其适合Elasticsearch。documents.json文件包含课程列表每个课程都有一个文档列表。我们将提取每个文档并向其中添加一个课程字段指示它属于哪个课程。
import jsonwith open(documents.json, rt) as f_in:docs_raw json.load(f_in)
Elasticsearch 要求所有内容都处于同一层次结构中在本例中我们有两个层次course 和 documents
documents []for course_dict in docs_raw:for doc in course_dict[documents]:doc[course] course_dict[course]documents.append(doc)documents[1]
#Output
{text: GitHub - DataTalksClub data-engineering-zoomcamp#prerequisites,section: General course-related questions,question: Course - What are the prerequisites for this course?,course: data-engineering-zoomcamp}3. 使用预训练模型创建嵌入
要执行语义搜索我们需要将文档转换为密集向量嵌入以捕获文本的语义含义。我们将使用来自 Sentence Transformers 库的预训练模型来生成这些嵌入。然后将这些嵌入编入 Elasticsearch 索引。这些嵌入使我们能够执行语义搜索其目标是找到与给定查询上下文相似的文本。
文本和问题字段是包含主要信息的实际数据字段而其他字段如 section 和 course则更具分类性信息量较少无法创建有意义的嵌入。
安装 sentence_transformers 库。加载预训练模型并使用它来为我们的文档生成嵌入。
from sentence_transformers import SentenceTransformer
model SentenceTransformer(all-mpnet-base-v2)#created the dense vector using the pre-trained model
operations []
for doc in documents:# Transforming the title into an embedding using the modeldoc[text_vector] model.encode(doc[text]).tolist()operations.append(doc) 4. 连接到 Elasticsearch
在此步骤中我们将建立与 Elasticsearch 实例的连接。确保 Elasticsearch 正在运行。
from elasticsearch import Elasticsearch# Connect to the Elasticsearch instance
es_client Elasticsearch(http://localhost:9200)
# Check the connection
print(es_client.info()) 5. 创建映射和索引
我们将定义映射并在 Elasticsearch 中创建索引生成的嵌入也将存储在其中。
映射是指定如何在 Elasticsearch 中构建和索引文档及其字段的过程。每个文档由各种字段组成每个字段都分配有特定的数据类型。
与数据库模式类似映射概述了文档的结构详细说明了字段、它们的数据类型例如字符串、整数或日期以及如何索引和存储这些字段。
通过定义文档和索引我们确保索引就像书中的目录一样有助于高效搜索。
index_settings {settings: {number_of_shards: 1,number_of_replicas: 0},mappings: {properties: {text: {type: text},section: {type: text},question: {type: text},course: {type: keyword},text_vector: {type: dense_vector, dims: 768, index: True, similarity: cosine},}}
}index_name course-questions
# Delete the index if it exists
es_client.indices.delete(indexindex_name, ignore_unavailableTrue)
# Create the index
es_client.indices.create(indexindex_name, bodyindex_settings)6. 将文档添加到索引
然后我们将预处理后的文档及其嵌入添加到 Elasticsearch 索引中。这使得 Elasticsearch 能够有效地存储和管理文档从而实现快速准确的搜索查询。
for doc in operations:try:es_client.index(indexindex_name, documentdoc)except Exception as e:print(e) 7. 查询搜索引擎
当用户输入搜索查询时它会被转换为嵌入并在 Elasticsearch 索引中进行搜索。结果会根据其与查询的相关性进行评分。
search_term windows or mac?
vector_search_term model.encode(search_term)query {field: text_vector,query_vector: vector_search_term,k: 5,num_candidates: 10000,
}
res es_client.search(indexindex_name, knnquery, source[text, section, question, course])
res[hits][hits]执行关键字搜索和高级搜索过滤结果
只要你直接使用用户输入并将该信息传递到你的搜索功能中这就变成了关键字搜索。
response es_client.search(indexindex_name,query{bool: {must: {multi_match: {query: windows or python?, fields: [text, question,course,title],type: best_fields}},filter: {term: {course: data-engineering-zoomcamp}}}}
) 执行语义搜索和高级搜索
为了让 Elasticsearch 执行语义搜索我们应该传递从最终用户那里收到的信息并将其转换为向量嵌入并且该向量嵌入是传递到搜索函数中的向量嵌入。
knn_query {field: text_vector,query_vector:vector_search_term,k: 5,num_candidates : 10000
}
responsees_client.search(indexindex_name,query{match: {course: data-engineering-zoomcamp},},knnknn_query,size5,explainTrue) 以下是主要步骤的简要介绍
将从最终用户收到的搜索词转换为向量嵌入。
将此向量嵌入传递到高级语义搜索函数中。将结果限制在特定部分在本例中为 “General course-related questions”。同样它可以限制为特定课程例如 “Data Engineering Zoom Camp.”。基本语义搜索和高级语义搜索之间的一个显着区别在于结果的评分。基本语义搜索分数范围在 0 到 1 之间其中 0 表示匹配度低1 表示匹配度高。
使用 Explain 关键字解释分数为了进一步了解分数计算Elasticsearch 提供了 explaintrue 关键字。此工具描述了如何计算分数提供了有价值的见解。有了这些信息人们可以开发出更符合特定用户或业务需求的自定义评分函数。 更多阅读请参阅Elasticsearch使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation 二