SEO技术

SEO技术

Products

当前位置:首页 > SEO技术 >

Elasticsearch全文搜索如何实现?

96SEO 2026-08-08 14:33 17


欢迎,

本实践教程将教你如何使用 Elasticsearch 建立一个完整的搜索方法。其实,在本教程中,你将学习:

  • 如何对数据集执行全文关键词搜索。并可选择使用过滤条件,
  • 如何使用机器学习模型生成、存储和搜索密集向量嵌入。不过,
  • 如何使用 ELSER 模型生成和搜索稀疏向量。
  • 如何使用 Elastic 的 Reciprocal Rank Fusion算法,将上述方法的搜索结果进行融合。

使用者痛点:在实际项目中。往往缺少从基础开始搭建完整搜索程序的实战案例,导致“想实现却找不到完整步骤”。本教程通过一步步来的小步骤,帮助你在本地项目中一次性实现所有功能。

Elasticsearch全文搜索如何实现?

本教程最关键的一点是它将向你展示如何在一个运行于你自己计算机上的项目中实现所有这些功能,而且整个过程通过一步步来的小步骤完成。

你将学习的示例使用 Python 编写。但其中的概念是通用的,可以应用于你喜欢的任何编程语言或技术栈。

为了利用本教程。我们建议你跟着教程一起操作,并运行所有示例。怎么说呢,

前提条件

要完成本教程。你需要安装以下组件:

  • 一个 Elasticsearch 安装运行环境,可以使用我们托管的 Elastic Cloud 服务,或者在你自己的计算机上运行一个自托管服务。安装说明请参阅上面的 “安装 Elasticsearch” 部分。如果你想使用 Elastic Cloud,请参考我之前录制的视频。在本展示中,我讲使用本地部署的 Elastic Stack 来进行展示。
  • 一个 Python 解释器。请确保使用较新的版本,例如 Python 3.9 或更高版本。

使用者痛点:很多开发者对 Elasticsearch 的部署方式感到困惑——不确定是选云端还是自建,甚至不知道如何快速启动一个实例。老实说,本节提供了两种常见方案,让你快速决定并落地。

技术基础

本教程假定你此前没有 Elasticsearch 或搜索相关主题的知识,但希望你至少具备以下技术的基础了解:

  • Python 开发
  • Python 的 Flask Web 框架
  • 操作程序中的命令提示符或终端应用程序

项目设置

下载入门应用程序

点击下面的链接下载搜索入门应用程序。


$ pwd
/Users/liuxg/python/tutorial
$ ls
search-tutorial-starter.zip

为你的项目选择一个合适的父目录。例如你的“文档”目录,并将压缩包内容解压到该目录中。解压后会生成一个名为 search-tutorial 的目录。其中包含多个子目录和文件:


$ pwd
/Users/liuxg/python/tutorial
$ tree -L 1
.
├── search-tutorial
│ ├── LICENSE
│ ├── README.md
│ ├── app.py
│ ├── data.json
│ ├── requirements.txt
│ ├── static
│ │ └── elastic-logo.svg
│ └── templates
│ ├── base.html
│ ├── document.html
│ └── index.html
└── search-tutorial-starter.zip

安装 Python 依赖项

  1. 创建并激活虚拟环境:
cd search-tutorial # 切换到项目根目录
python3 -m venv .venv # 创建虚拟环境
# 激活虚拟环境
source .venv/bin/activate
# 若在 Windows PowerShell 中:
# .venv\Scripts\activate

*注意*: 虚拟环境仅在当前终端会话有效,关闭窗口后需重新激活。

  1. 安装依赖包:
pip install -r requirements.txt
pip freeze> requirements.txt # 保持 requirements 同步

运行应用程序

flask run # 启动 Flask 开发服务器

A 浏览器访问  确认页面加载。此时页面仅显示空壳,暂无搜索结果,后续章节会逐步填充功能。

设置 Elasticsearch Python 客户端

安装客户端库

pip install elasticsearch
pip list | grep elasticsearch # 验证已安装版本与 ES stack 匹配

连接到 Elasticsearch 服务

Create a new file /search-tutorial/search.py,n add following code:


import json
from pprint import pprint
import os
import time
from dotenv import load_dotenv
from elasticsearch import Elasticsearch
load_dotenv
class Search:
def __init__:
# 以下两段任选其一,# ---- Elastic Cloud 示例 -----
# self.es = Elasticsearch(
# cloud_id=os.getenv,# api_key=os.getenv
# )
# ---- 本地自托管示例 -----
self.es = Elasticsearch(
os.getenv,api_key=os.getenv,verify_certs=False,ssl_show_warn=False。)
client_info = self.es.info
print
pprint
# 基础 CRUD 方法将在后续章节补全...

The connection parameters are read from a hidden .env. Create it in project root:


# 对于 Elastic Cloud:
ELASTIC_CLOUD_ID=your_cloud_id_here
ELASTIC_API_KEY=your_api_key_here
# 对于本地部署:
ES_URL=https://localhost:9200 # 根据实际端口调整
ES_API_KEY=your_local_api_key_here # 如未启用,可留空但保持键名存在

Add file name to .gitignore,防止凭据泄露:


echo ".env">> .gitignore

测试连接是否成功

  1. Python REPL 中导入并实例化:

>> from search import Search # 导入类
>> es = Search # 实例化,会打印连接信息
Connected to Elasticsearch!{'cluster_name': 'elasticsearch','name': 'my-node',...}
>>

If you encounter errors,double‑check your credentials in .env,ensure ES service is running and reachable.

把客户端整合进 Flask 应用

  • Edit /search-tutorial/app.py 。add:

from search import Search
app = Flask
es = Search # 全局实例,可供所有路由调用
...
Now every request can use global `es` object.

创建索引

Create Index 方法

python class Search: ... def create_index: self.es.indices.delete self.es.indices.create
  • The index name is hard‑coded for simplicity;in real projects you may pass it as an argument.

Add Documents 方法

python def insert_document: return self.es.index
def insert_documents:
ops =
for doc in documents:
ops.append
ops.append
return self.es.bulk
    Bulk API dramatically reduces indexing time compared with single‑document calls.

python def reindex: self.create_index with open as f: docs = json.load return self.insert_documents

Add a Flask CLI command for easy re‑indexing:

python @app.cli.command def reindex: """Regenerate Elasticsearch index.""" resp = es.reindex print} docs in {resp} ms')

User Pain Point: 手动删除旧索引、重新创建、批量导入很繁琐;通过 CLI 一键搞定,


Create a simple search wrapper

python class Search: ... def search: return self.es.search


Match Query

Edit app.py → handle_search:

python @app.post def handle_search: query = request.form.get results = es.search( query={'match': {'name': {'query': query}}} ) hits = results total = results return render_template('index.html'。results=hits,query=query,from_=0,total=total)

Now you can search by document title .

Pain point: 初始实现只能匹配标题,很多业务需求需要同时匹配正文与摘要,这里仅演示了最基础的单字段匹配。


Multi‑Match

Upgrade to multi‑match so title、summary、content 都参与检索:

python @app.post def handle_search: query = request.form.get results = es.search( query={'multi_match': {'query': query,'fields': }} ) ...


Pagination

Add size & from_ parameters :

python @app.post def handlesearch: query = request.form.get from = request.form.get

results = es.search(
query={...},# 上面的 multi_match 块保持不变
size=10,from_=from_
)

...

Update templates/index.html to display pagination controls:

+jinja2

Showing {{ from_ + 1 }}–{{ from_ + results|length }} out of {{ total }} {% if from> 0 %} {% endif %} {% if from + results|length
--- ### Filter Support #### Boolean Query Skeleton json5 { 再看"bool"。{ "must"这方面,"filter": } } #### Extract filter expressions from user input Add helper in **app.py**: python def extract_filters: filters= # category filter e.g. "category:github" cat_match=re.search',query) if cat_match: filters.append({ "term"的观点是,{"category.keyword":{"value":cat_match.group}} }) query=re.sub.strip # year filter e.g. "year:2022" yr_match=re.search',query) if yr_match: year=yr_match.group filters.append({ "range":{"updated_at":{ "gte"这方面,f"{year}||/y","lte":f"{year}||/y" }} }) query=re.sub.strip return {"filter":filters},query #### Integrate filters into search endpoint python @app.post def handle_search: raw_query=request.form.get filters,clean_query=extract_filters from_=request.form.get if clean_query: must_clause={"multi_match": {"query":clean_query,"fields":}} else的观点是,must_clause={"match_all":{}} body={"bool":{"must":must_clause,"filter":filters}} resp=es.search ... **Pain point:** 使用者常抱怨“只能全局搜索,无法按分类或时间筛选”。通过正则解析过滤语法,实现了轻量级、可 的过滤机制。--- ### Match‑All fallback When only filters are supplied we replace `multi_match` with `match_all` so that filter alone returns results. The updated endpoint already handles this case . --- ## Faceted Search Facets give users quick access to common filter options toger with result counts. ### Terms Aggregation for Category Add aggregations to same search call: python resp=es.search( query=body,aggs={ "category-agg":{"terms":{"field":"category.keyword"}},"year-agg":{ "date_histogram":{ "field":"updated_at","calendar_interval":"year","format":"yyyy" } } },size=10,from_=from_ ) ### Transform aggregation response for template rendering python aggs={ "Category":{ bucket的观点是。bucket for bucket in resp },"Year":{ bucket这方面,bucket for bucket in resp if bucket> 0 # skip empty years } } return render_template("index.html",results=resp,query=raw_query,from_=from_,total=resp,aggs=aggs) ### Template snippet – renders facets as clickable forms +jinja2 {% for agg_name,buckets in aggs.items %}
{{ agg_name }}
{% for key,count in buckets.items %} {% set new_query=query ~ ' ' ~ agg_name|lower ~ ':' ~ key %} {{ new_query }} {{ new_query }} {{ key }}

{% endfor %} {% endfor %}

Pain point: 手动统计每个分类/年份数量非常耗时;其实,聚合一次请求即可返回全部统计信息,明显提高交互体验。说起来,


完整代码概览

Below is a condensed view of all files after completing tutorial steps.

app.py

python import re from flask import Flask,render_template,request from search import Search

app = Flask es = Search

def extract_filters: filters=

------

@app.get def index: return render_template

@app.post def handlesearch: rawquery=request.form.get filters,cleanquery=extractfilters

--- 构造 bool 查询体 ---

results=es.search aggs={...} return render_template

@app.get def getdocument: doc=es.retrievedocument title=doc paragraphs=doc.split return render_template("document.html",title=title。paragraphs=paragraphs)

if name=='main': app.run

search.py

python import json import os import time from dotenv import load_dotenv from elasticsearch import Elasticsearch

load_dotenv

class Search: def init: self.es = Elasticsearch( os.getenv,apikey=os.getenv,verifycerts=False,sslshowwarn=False )

 info=self.es.info
print
print
def create_index:
self.es.indices.delete(index='my_documents',ignore_unavailable=True)
self.es.indices.create
def insert_document:
return self.es.index
def insert_documents:
ops=
for d in docs:
ops.append
ops.append
return self.es.bulk
def reindex:
self.create_index
with open as f:
docs=json.load
return self.insert_documents
def retrieve_document:
return self.es.get
def search:
return self.es.search

templates/index.html

+jinja2

…输入框 ,

{% for result in results %}

\ {{ result._source.summary }}\ <\/span>\ …

{% endfor %}

{% if from_>0 %} …{% endif %}

{% if from_ + results|length {% endif %}

…


小结 & 常见痛点回顾

痛点 本教程对应方法
不知道怎么快速启动 ES 环境 提供 Cloud 与自托管两套详细步骤
手动批量导入慢且易出错 使用 Bulk API 一键导入全部文档
只支持单字段检索,业务需求不满足 Multi‑Match 跨字段检索
结果太多。没有分页 Size + From 参数 + 前后页按钮
缺少筛选能力,只能全局搜索 正则解析 “category:” 与 “year:” 并转成 Bool Filter
只靠关键词检索,不知道哪些筛选项受欢迎 Terms & Date Histogram 聚合实现 Faceted UI
部署后每次改动都要手动重建索引 Flask CLI reindex 命令一键刷新

通过以上步骤,你已经拥有了:

  • 可运行于本地或云端的完整 Elastic 搜索服务;
  • 基础 CRUD、批量导入、全文检索、多字段查询;
  • 分页、过滤、还有动态聚合;
  • 与 Flask 前端完美结合,可直接打开浏览器交互。不过,

现在可以继续探索更高级特性。如向量相似度检索、ELSER 稀疏模型、RRF 融合等。祝开发顺利,

。


标签: 教程

SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback