基于Django的博客系统之用HayStack连接elasticsearch增加搜索功能(五)

上一篇:搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL(四)
下一篇:基于Django的博客系统之增加类别导航栏(六)

功能概述

  1. 添加搜索框用于搜索博客。

需求详细描述

1. 添加搜索框用于搜索博客

  • 描述: 在博客首页添加搜索框,用户可以通过关键词搜索博客文章。
  • 功能要求:
    • 搜索框位置:导航栏或页面顶部。
    • 支持根据标题和内容进行搜索。
    • 搜索结果显示匹配的博客列表。
  • 用户故事:
    • 作为用户,我希望能够通过搜索框快速找到感兴趣的博客文章。

技术结构

实现一个博客搜索功能,可以同时使用 Elasticsearch 和 MySQL 各自的优势。以下是如何区分和结合使用这两种技术的方法:

使用 MySQL 的部分

  1. 数据存储
    • 存储博客文章的基本信息,如标题、作者、发布时间、分类等。
    • 存储用户信息、评论、标签等结构化数据。
  2. 基础查询和管理
    • 进行常规的 CRUD 操作,如创建、读取、更新、删除博客文章。
    • 进行简单的过滤和排序,如按发布时间、作者、分类等查询文章。

使用 Elasticsearch 的部分

  1. 全文搜索
    • 存储和索引博客文章的全文内容,以支持全文搜索功能。
    • 对用户搜索的关键词进行快速匹配,返回相关的文章列表。
  2. 复杂查询
    • 支持复杂的查询需求,如模糊搜索、布尔搜索、按相关性排序等。
    • 支持自动补全、拼写纠错等高级搜索功能。

集成 MySQL 和 Elasticsearch

  1. 数据同步
    • 需要将 MySQL 中的博客文章数据同步到 Elasticsearch 中,以确保搜索功能能够使用最新的数据。
    • 可以使用定时任务或实时数据同步机制来保持两者数据的一致性。例如,使用工具如 Logstash、Beats 或自定义的同步程序。
  2. 搜索接口设计
    • 提供一个统一的搜索接口,前端用户提交搜索请求时,后台从 Elasticsearch 中查询搜索结果。
    • 查询到的搜索结果中包含文章的基本信息,从 Elasticsearch 返回文章的 ID,然后从 MySQL 中获取详细信息(如作者、评论等)。

实现步骤

要在 Django 博客应用中添加搜索框,以便用户可以搜索博客内容,可以按照以下步骤进行:

1. 安装 Django 搜索库

首先,确保你已经安装了 Django 搜索库。一个常用的选择是 django-haystack 库,它提供了与多个搜索引擎(如 Elasticsearch、Solr 和 Whoosh 等)集成的功能。

pip install django-haystack

2. 配置搜索引擎

选择并配置你想要使用的搜索引擎。例如,如果选择使用 Whoosh 搜索引擎,需要在 settings.py 文件中配置 Haystack 设置:

# settings.pyINSTALLED_APPS = [# 其他应用...'haystack',
]HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine','URL': 'http://localhost:9200/',  # Elasticsearch 服务器的 URL'INDEX_NAME': 'haystack',  # Elasticsearch 索引的名称},
}HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

3. 创建搜索索引类

为你的博客模型创建一个搜索索引类,告诉 Haystack 如何索引你的数据。假设你有一个名为 Post 的博客模型:

# search_indexes.pyfrom haystack import indexes
from .models import Postclass PostIndex(indexes.SearchIndex, indexes.Indexable):text = indexes.CharField(document=True, use_template=True)def get_model(self):return Post

在这个示例中,我们使用 text 字段来索引博客内容。你可以根据需要添加更多的字段。

4. 创建搜索模板

在你的博客模板文件夹中创建一个模板文件,用于显示搜索结果。这个模板将根据搜索结果显示匹配的博客文章。

<!-- templates/search/post_text.txt -->{{ object.title }}
{{ object.content }}

同步索引:运行 Django 的管理命令来创建或更新搜索索引。

python manage.py rebuild_index

5. 更新 URL 配置

将搜索视图添加到你的 URL 配置中,以便用户可以访问搜索页面并执行搜索。

# urls.pyfrom django.urls import path
from . import viewsurlpatterns = [# 其他 URL 配置...path('search/', views.SearchView.as_view(), name='search'),
]

6. 创建搜索视图

创建一个视图类来处理搜索请求,并将搜索结果呈现给用户。

from haystack.query import SearchQuerySetdef search_view(request):query = request.GET.get('q', '')results = SearchQuerySet().filter(content=query)return render(request, 'search_results.html', {'results': results})

7. 创建搜索模板

创建一个模板文件,用于显示搜索结果。在这个模板中,你可以根据需要定制搜索结果的展示方式。

<!-- templates/search.html -->{% for result in page.object_list %}<h3><a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a></h3><p>{{ result.object.content }}</p>
{% empty %}<p>No results found.</p>
{% endfor %}{% if is_paginated %}<div class="pagination"><span class="step-links">{% if page.has_previous %}<a href="?q={{ query }}&page=1">&laquo; first</a><a href="?q={{ query }}&page={{ page.previous_page_number }}">previous</a>{% endif %}<span class="current">Page {{ page.number }} of {{ page.paginator.num_pages }}.</span>{% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">next</a><a href="?q={{ query }}&page={{ page.paginator.num_pages }}">last &raquo;</a>{% endif %}</span></div>
{% endif %}

8. 创建搜索表单

最后,创建一个搜索表单,让用户输入搜索关键字并提交搜索请求。

<!-- templates/search_form.html --><form action="{% url 'search' %}" method="get"><input type="text" name="q" placeholder="Search..."><button type="submit">Search</button>
</form>

将搜索表单包含在你的博客页面中的适当位置,用户就可以使用它来搜索博客内容了。

这就是在 Django 博客应用中添加搜索框的基本步骤。根据你的需求,你可以进一步定制搜索功能,例如添加搜索结果的高亮显示、自定义搜索表单字段等。

连接elasticsearch

具体参看这篇Windows安装ElasticSearch版本7.17.0

要连接 Elasticsearch,你需要配置 Django Haystack 的后端为 Elasticsearch 后端。下面是一些步骤:

  1. 安装 Elasticsearch:首先确保你已经安装了 Elasticsearch 并且它正在运行。你可以从 Elasticsearch 的官方网站上下载并安装它。
  2. 安装 Haystack:确保你已经安装了 Django Haystack。你可以使用 pip 进行安装:pip install django-haystack
  3. 安装 Elasticsearch 后端:你需要安装与 Elasticsearch 兼容的 Haystack 后端。通常情况下,你需要安装 elasticsearch-dsl,它是 Elasticsearch 的 Python 客户端库。你可以使用 pip 进行安装:pip install elasticsearch-dsl
  4. 配置 Haystack 设置:在 Django 项目的 settings.py 文件中,配置 Haystack 设置以使用 Elasticsearch 后端。这包括指定 Elasticsearch 的主机和端口等信息。
HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine','URL': 'http://localhost:9200/',  # Elasticsearch 服务器的 URL'INDEX_NAME': 'haystack',  # Elasticsearch 索引的名称},
}
  1. 建立索引:运行 python manage.py rebuild_index 命令来建立你的模型的搜索索引。这将会在 Elasticsearch 中创建对应的索引。
  2. 运行你的应用程序:现在你的 Django 应用程序应该能够连接到 Elasticsearch 并使用它来进行全文搜索了。

问题和解决

报错 from django.utils.datetime_safe import date, datetime ModuleNotFoundError: No module named 'django.utils.datetime_safe'

分析解决:

在 Django 3.2 中,django.utils.datetime_safe 模块已被移除。这个模块提供了在处理日期和时间时的安全操作,以防止由于 datetimedate 对象的类型不同而导致的一些问题。

如果你的代码中依赖了 django.utils.datetime_safe 模块,你可以尝试以下替代方法:

  1. 直接使用 datetime 和 date:在绝大多数情况下,直接使用内置的 datetimedate 类应该没有问题。只要确保在处理日期和时间时,类型的转换和比较是正确的即可。
  2. 在需要的地方进行转换:如果你的代码在某些情况下需要确保 datetimedate 对象的类型一致,你可以手动进行转换。比如,使用 timezone.now() 获取当前时间,使用 datetime.strptime() 将字符串转换为 datetime 对象等。
  3. 更新依赖:如果你使用的是第三方库,可以尝试更新这些库的版本,看看是否有与 Django 3.2 兼容的版本。

确保你的代码不再依赖于 django.utils.datetime_safe 模块后,就可以解决这个错误了。切换为elasticsearch连接。报错如下 raise MissingDependency( haystack.exceptions.MissingDependency: The 'elasticsearch5' backend requires the installation of 'elasticsearch>=5.0.0,<6.0.0'. Please refer to the documentation.

在这里插入图片描述

修改settings.pyHAYSTACK_CONNECTIONS连接的Elasticsearch版本为8.x,如下:

HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.backends.elasticsearch8_backend.Elasticsearch8SearchEngine','URL': 'http://localhost:9200/','INDEX_NAME': 'myblog',},
}

报错ModuleNotFoundError: No module named 'haystack.backends.elasticsearch8_backend'

原因:Haystack中没有提供一个专门用于Elasticsearch 8.x 的后端引擎。使用 haystack.backends.elasticsearch7_backend.Elasticsearch7SearchEngine 就可以支持 Elasticsearch 7.x。

重新安装elasticsearch版本号为7.17。见这篇文章

卸载不需要的驱动

pip uninstall elasticsearch
pip uninstall elasticsearch-dsl

安装需要的驱动

 pip install elasticsearch==7.17.0pip install elasticsearch-dsl==7.4.1

再次调用启动搜索index命令python manage.py rebuild_index

报错ImportError: cannot import name 'datetime_safe' from 'django.utils'

原因:Django 3.2 中移除了 django.utils.datetime_safe 模块引起的。Haystack 应该已经更新以适应 Django 3.2。

执行命令下载haystack支持django5.0.7

pip install git+https://github.com/django-haystack/django-haystack.git

再次调用启动搜索index命令

python manage.py rebuild_index

运行成功。效果如下:

在这里插入图片描述

调用http://localhost:8000/search/?q=%E6%AF%94%E4%BC%AF后,结果如下:

在这里插入图片描述

分析原因elasticsearch的index有问题。

tree /F命令获取全文件夹下的文件格式表。

通过下面命令获取当前elasticsearch里面的index

Invoke-WebRequest -Uri "http://localhost:9200/_cat/indices?v"

post_text.txt里面添加一段index的指向

<!-- templates/search/indexes/blog/post_text.txt -->

执行index命令python manage.py rebuild_index

执行成功,如下:
在这里插入图片描述
postman调用apihttp://localhost:9200/myblog结果返回成功:

{"myblog": {"aliases": {},"mappings": {"properties": {"content": {"type": "text","analyzer": "snowball"},"django_ct": {"type": "keyword"},"django_id": {"type": "keyword"},"id": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"text": {"type": "text","analyzer": "snowball"},"title": {"type": "text","analyzer": "snowball"}}},"settings": {"index": {"max_ngram_diff": "2","routing": {"allocation": {"include": {"_tier_preference": "data_content"}}},"number_of_shards": "1","provided_name": "myblog","creation_date": "1716964128114","analysis": {"filter": {"haystack_ngram": {"type": "ngram","min_gram": "3","max_gram": "4"},"haystack_edgengram": {"type": "edge_ngram","min_gram": "2","max_gram": "15"}},"analyzer": {"edgengram_analyzer": {"filter": ["haystack_edgengram","lowercase"],"tokenizer": "standard"},"ngram_analyzer": {"filter": ["haystack_ngram","lowercase"],"tokenizer": "standard"}}},"number_of_replicas": "1","uuid": "1GzZNjZzSmOtmFdLuGWhvw","version": {"created": "7170099"}}}}
}

搜索index

修改搜索视图以获取匹配的博客文章 ID,并从 MySQL 中获取详细信息:

# blog/views.py
from django.shortcuts import render
from haystack.query import SearchQuerySet
from .models import BlogPost
from .forms import BlogSearchFormdef search(request):form = BlogSearchForm(request.GET)results = []if form.is_valid():# 从 Elasticsearch 获取匹配的博客文章 IDsqs = form.search()matched_ids = [result.pk for result in sqs]# 从 MySQL 数据库中获取详细信息results = BlogPost.objects.filter(id__in=matched_ids)return render(request, 'search_results.html', {'form': form, 'results': results})

访问’http://localhost:8000’输入搜索growing,访问’http://localhost:8000/search/?q=growing’,得到结果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/21309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据密集型系统设计】软件系统的可靠性、可伸缩性、可维护性

文章目录 一. 数据密集型程序的特点以及遇到的问题二. 可靠性 : 即使出现问题&#xff0c;也能继续正确工作1 硬件故障2. 软件错误3. 人为错误 二. 可伸缩性1. 描述负载与推特的例子2. 描述性能-延迟和响应时间3. 应对负载的方法 四. 可维护性1. 可操作性&#xff1a;人生苦短&…

如何解决Mac系统创建/home目录提示Read-Only filesystem(补充)?

继昨日发布的博文之后&#xff0c;有小伙伴私我说&#xff1a; sudo mount -uw /命令报错&#xff1a;mount_apfs: volume could not be mounted: Permission denied mount: / failed with 66 今天补充一下昨天的文章&#xff0c;昨天的文章我没有注明是Mac什么系统的&#x…

Chromebook Plus中添加了Gemini?

Chromebook Plus中添加了Gemini&#xff1f; 前言 就在5月29日&#xff0c;谷歌宣布了一项重大更新&#xff0c;将其Gemini人工智能技术集成到Chromebook Plus笔记本电脑中。这项技术此前已应用于谷歌的其他设备。华硕和惠普已经在市场上销售的Chromebook Plus机型&#xff0c;…

mysql binlog查看指定数据库

1.mysql binlog查看指定数据库的方法 MySQL 的 binlog&#xff08;二进制日志&#xff09;主要记录了数据库上执行的所有更改数据的 SQL 语句&#xff0c;包括数据的插入、更新和删除等操作。但直接查看 binlog 并不直观&#xff0c;因为它是以二进制格式存储的。为了查看 bin…

电脑缺少dll文件怎么解决,分享几种靠谱的解决方法

在现代科技高度发达的时代&#xff0c;电脑已经成为我们生活和工作中不可或缺的工具。然而&#xff0c;在使用电脑的过程中&#xff0c;我们可能会遇到一些问题&#xff0c;其中之一就是电脑丢失dll文件。那么&#xff0c;当我们面临这样的问题时&#xff0c;应该如何解决呢&am…

云原生架构案例分析_1.某旅行公司云原生改造

随着云计算的普及与云原生的广泛应用&#xff0c;越来越多的从业者、决策者清晰地认识到“云原生化将成为企业技术创新的关键要素&#xff0c;也是完成企业数字化转型的最短路径”。因此&#xff0c;具有前瞻思维的互联网企业从应用诞生之初就扎根于云端&#xff0c;谨慎稳重的…

BMC压力测试脚本

说明 对于研发阶段而言&#xff0c;需要对BMC执行压力测试&#xff0c;可以提前发现问题&#xff0c;修复问题&#xff0c;提高产品稳定性。 大体而言&#xff0c;需要做到几个方面: 1.预先发现是否会造成BMC hang机。2.进程是否会发生重启&#xff0c;运行异常3.进程是否会…

SpringMVC:转发和重定向

1. 请求转发和重定向简介 参考该链接第9点 2. forward 返回下一个资源路径&#xff0c;请求转发固定格式&#xff1a;return "forward:资源路径"如 return "forward:/b" 此时为一次请求返回逻辑视图名称 返回逻辑视图不指定方式时都会默认使用请求转发in…

【Qt秘籍】[008]-Qt中的connect函数

在Qt框架中&#xff0c;connect函数是一个非常核心的函数&#xff0c;用于实现信号&#xff08;Signals&#xff09;和槽&#xff08;Slots&#xff09;之间的连接&#xff0c;它是Qt信号槽机制的关键所在。信号槽机制是一种高级的通信方式&#xff0c;允许对象在状态改变时通知…

ChatGPT-3

ChatGPT-3是OpenAI开发的先进人工智能聊天机器人程序&#xff0c;它是基于 GPT-3.5 架构的大型语言模型&#xff0c;并通过强化学习进行了训练。这项技术代表了自然语言处理领域的一个重要里程碑&#xff0c;具有以下显著特点和功能&#xff1a; 强大的语言理解和生成能力&…

代码随想三刷数组篇

代码随想三刷数组篇1 704. 二分查找题目代码27. 移除元素题目代码977.有序数组的平方题目代码209.长度最小的子数组题目代码59.螺旋矩阵II题目代码704. 二分查找 题目

牛客网刷题 | BC114 圣诞树 (不理解)

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 这道题没搞懂 也没找到视…

Nginx源码编译安装

Nginx NginxNginx的特点Nginx的使用场景Nginx 有哪些进程 使用源码编译安装Nginx准备工作安装依赖包编译安装Nginx检查、启动、重启、停止 nginx服务配置 Nginx 系统服务方法一&#xff1a;方法二&#xff1a; 访问Nginx页面 升级Nginx准备工作编译安装新版本Nginx验证 Nginx N…

【HarmonyOS】Stage 模型 - UIAbility 的启动模式

Stage 模型这样的应用&#xff0c;它在启动的时候会先准备 Ability Stage 舞台&#xff0c;接着呢&#xff0c;就可以基于它去创建 UIAbility 的实例&#xff0c;并去启动它。 UIAbility 组件启动模式 有四种&#xff1a; singletonstandardmultitonspecified 修改模块的 mod…

SSMP整合案例第五步 在前端页面上拿到service层调数据库里的数据后列表

在前端页面上列表 我们首先看看前端页面 我们已经把数据传入前端控制台 再看看我们的代码是怎么写的 我们展示 数据来自图dataList 在这里 我们要把数据填进去 就能展示在前端页面上 用的是前端数据双向绑定 axios发送异步请求 函数 //钩子函数&#xff0c;VUE对象初始化…

【四大组件】-- 活动 Activity

目录 活动活动是什么活动的相关操作手动创建活动活动中使用Toast活动中使用Menu销毁一个活动 使用Intent实现活动间启动显示启动隐式启动 活动间数据传递活动的生命周期返回栈活动的状态活动的生存期 活动的启动流程活动的回收和重建如何在活动销毁前保存状态 活动的启动模式st…

设计模式(十四)行为型模式---访问者模式(visitor)

文章目录 访问者模式简介分派的分类什么是双分派&#xff1f;结构UML图具体实现UML图代码实现 优缺点 访问者模式简介 访问者模式&#xff08;visitor pattern&#xff09;是封装一些作用于某种数据结构中的元素的操作&#xff0c;它可以在不改变这个数据结构&#xff08;实现…

红队内网攻防渗透:内网渗透之windows内网权限提升技术:手工篇

红队内网攻防渗透 1. 内网权限提升技术1.1 windows内网权限提升技术--手工篇1.1.1 Web到Win-系统提权-人工操作1.1.1.1 信息收集1.1.1.2 补丁筛选1.1.1.3 EXP获取执行1.1.2 Web到Win-系统提权-土豆家族1.1.2.1 Test in:Windows 10/11(1809/21H2)1.1.2.2 Test in:Windows Se…

全新市场阶段,Partisia BlockChain 将向 RWA、DeFi 等领域布局

Partisia Blockchain 是一个全新范式的 Layer1&#xff0c;该链通过 MPC 方案来构建链上隐私方案&#xff0c;同时该链通过系列独特且创新的设计&#xff0c;旨在进一步解决目前 Web3 中所面临的不可能三角问题&#xff0c;包括安全性、互操作性和可扩展性&#xff0c;为更多的…

NTFS磁盘格式读写工具:Tuxera NTFS 2021 for Mac

Tuxera NTFS 是一款用于 macOS 系统的 NTFS 文件系统驱动程序。NTFS 是 Windows 系统中常用的文件系统&#xff0c;而 macOS 默认只支持读取 NTFS 格式的磁盘&#xff0c;不能进行写入操作。因此&#xff0c;如果你需要在 macOS 上进行 NTFS 磁盘的写入操作&#xff0c;就需要安…