使用django-haystack+whoosh实现全文搜索

发布于:2024-07-11 ⋅ 阅读:(16) ⋅ 点赞:(0)

前言

好像是上个星期在写代码的时候遇到了一些问题,这个问题似乎我之前也遇到过,印象中好像也写博客进行记录了的,于是就想在我的博客系统中“查找”(表示很无奈居然没有搜索功能🥹🥹),于是就利用现有的过滤功能进行查找,但之前的分类和标签早就不记得了😅 ,于是就一直没有找到,但印象中确实写过相关内容…所以就有点尴尬了…😅😅😅,所以为了解决这个问题,花了将近一整天的时间给博客系统加了一个全文搜索的功能。

前景概要

作为一个博客系统,搜索应该算是一个最基础的功能,但是为啥我一直没有添加?因为我也是有“苦衷”的。在上一个版本中是有这搜索功能的,但是自从使用了vitepress之后,它就没了,原因很简单,我对vitepress进行了“魔改”,vitepress的初衷是一个静态文本系统,也内置了搜索功能,但是博客系统得是动态的,与vitepress的理念是相反的,所以为了既要用vitepress的生态,也要支持“动态”功能,我对vitepress进行了魔改(这是一段艰苦而漫长的旅程),最后,它不会一次性把所有内容加载到前端,就无法使用它内置的local搜索了(algolia我没有考虑),所以也就一直没有搜索功能了…
所以,就这样为了实现博客系统的“动态”的需求,我把vitepress的搜索功能给整没了!我也尝试过去添加,但是最终都以失败告终,最终以为可以添加一个过滤功能来弥补它,但终究还是弥补不了…☹️

:::TIPS
上面提到的vitepress的静态和博客系统的动态的区别是:vitepress在build的时候会把所有的博客都build,在浏览器请求的时候也是一次性拿到所有的博客内容,这样它才能在前端实现搜索功能;而我所需要的是用户在请求一篇博客时就请求后端拿这篇博客的内容,所以这两者基本上是互相驳斥的。

:::

既要,又要,还要!

上面我为了既要viteoress的生态,也要博客系统支持“动态”加载的功能,我对vitepress进行魔改,导致搜索功能用不了了,但今天,完既要,又要,还要哈哈哈,我还要它的搜索功能!!!
OK,上面讲了一大堆废话,下面开始我们的正文吧!🙃🙃🙃

正文

重写vitepress的默认组件

我一开始想到的是直接修改它的源码,但是这样是一件吃力不讨好的事情(尝试过的人应该都知道,没尝试过的可以试试哈哈哈),于是就在网上不断搜索寻找解决方案,就在我找得快要绝望时,我在官方文档看到了曙光哈哈哈,它在介绍扩展默认主题的页面中介绍了一种重写默认组件的方法,也给出了示例代码:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vitepress'

export default defineConfig({
  vite: {
    resolve: {
      alias: [
        {
          find: /^.*\/VPNavBar\.vue$/,
          replacement: fileURLToPath(
            new URL('./components/CustomNavBar.vue', import.meta.url)
          )
        }
      ]
    }
  }
})

所以,按照它的思路,只要我找到搜索的组件,然后把它替换成我自己的,那么就可以实现自定义的搜索功能了!

替换默认的搜索组件

如果使用的是local方式的话,它的搜索组件就是VPLocalSearchBox.vue,因此我这里直接把它替换成我自定义的MyVPLocalSearchBox.vue

image.badd226a3c6c11efbb7c00163e16d300.png
其中我自定义的搜索组件的内容,其实大部分都是复制它原有的,只不过把它的搜索源换成了我自己的后端。
image.8849c17c3c6d11efaffd00163e16d300.png

使用django-haystack+whoosh实现全文搜索的接口

前段的任务完成后,现在就只差一个后端接口了!
我一开始想到的是就是直接使用sql进行过滤搜索,以及顶多一个模糊匹配,但是这样我试了几下,效率都不在我的接受范围之内,于是想到了全文搜索会不会更快些?于是在网上找到了一些文章,看大家都是使用django-haystack在django中实现的全文搜索,于是我也就入坑了,它其实就是整合了一些搜索引擎,抽象了一层接口,增加了对这些搜索引擎的支持,它支持的搜索引擎如下:
image.c0ecbcea3c6e11efa5cd00163e16d300.png
我一开始尝试使用了elasticsearch,但是发现它还需要额外的依赖(这里我指的是python以外的依赖),感觉比较麻烦,最后发现whoosh它是纯python实现的,所以相比于其他的,它是相对友好的一个!
image.62bf613a3c6f11ef8bbd00163e16d300.png

配置流程

关于haystack使用whoosh进行全文搜索在Django中的配置流程,我搜索到的几篇博客都大同小异,其实都是参考官方的流程来的,这里给出官方的配置流程
image.e42638b63c6f11ef8bbd00163e16d300.png

自定义搜索接口

根据官方的配置流程,你会发现,它配置了templates,最后返回的是一个html,搜索的逻辑在它自己的代码中,所以要实现一个返回json数据的接口,我们就得自定义:
image.885ed7a83c7011efb4ef00163e16d300.png
其实和django自带的写法差不多,这里用到了haystack的接口:SearchQuerySet。

到这里差不多就结束了,来试一下搜索功能叭~
image.1eae91023c7711efa72400163e16d300.png

perfect~~~😎😎😎

更多内容可以关注博主的个人博客系统:使用django-haystack+whoosh实现全文搜索