Wagtail 配置中文全文检索

Django是我学习的第一个web框架。多年前,家人手术住院,我陪床,闲着无事,我跟着Django教程一步一步实现了一个简单的留言板,并部署到了一个免费的空间。我把链接发给好友,那种喜悦和成就感至今还记得,也让我开始对Python编程产生了浓厚的兴趣。后来用过web.py、Tornado、fastapi等多种框架。但是开始一个新项目时,大多时候Django是我的首选,功能完善,开箱即用。

Wagtail是一个基于Django开发的CMS系统,它不能直接使用,而是需要有经验的Python程序员基于它去开发自己的网站。它提供了优美、丰富、实用的后台管理界面,也基于Django扩展了很多方便开发的模块和功能。有趣的是,我第一次用这个框架时曾经去查询过wagtail这个单词的意思是一种叫“鹡鸰”的小鸟,面对这两个生僻的字,我瞄了一眼就关上了网页。前一阵子在贵州高速的一个服务区看到了一只很特别的小鸟,用识图App查到它就是白鹡鸰,而且挺常见的。但直到最近我用Wagtail开发我自己的博客程序,我才把两者联系到一起,也发现Wagtail log上的那只小鸟很传神。

之前用Tornado开发博客时,几乎是手写的SQL语句来实现包括全文检索在内的查询,简单,纯粹。而使用Wagtail,在通读了官方文档后,只需要很少的代码和很少的配置就可以实现了。Wagtail支持数据库和Elasticseach作为搜索后端,我的内容不多,托管程序的服务器的内存也有限,就选择了我比较熟悉和喜欢的PostgreSQL作为数据库和搜索后端。

我这里使用的软件包版本如下,版本差异较大的话,api可能会有修改,我以当前使用的版本为例。

Django>=4.1,<4.2
wagtail>=4.2,<4.3

配置PostgreSQL

因为PostgreSQL默认不支持中文分词,所以需要安装对应的插件。我在之前博文中写过如何配置了,再次不再赘述,建议用Docker去运行自己的PostgreSQL实例。

配置数据库

需要在你使用的数据库执行几行sql语句,用于创建全文检索的配置文件,如果使用Django的话,可以写在migrations里边,如下,

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        # 导入 SQL 语句
        migrations.RunSQL('''
            CREATE EXTENSION zhparser;
            CREATE TEXT SEARCH CONFIGURATION zh (PARSER = zhparser);
            ALTER TEXT SEARCH CONFIGURATION zh ADD MAPPING FOR n,v,a,i,e,l WITH simple;
        '''),
    ]

这里边的“zh”是配置的名称,可以自定义,只要和代码里保持一致即可

设置Wagtail程序

首先在项目的配置文件指定使用的配置名称

WAGTAILSEARCH_BACKENDS = {
    "default": {
        "BACKEND": "wagtail.search.backends.database",
        'SEARCH_CONFIG': 'zh',
    }
}

这里我们添加了SEARCH_CONFIG这个配置项,如果不进行指定,系统使用的默认配置文件对于中文效果很差。

在model上指定搜索的字段,

class BlogEntry(Page): 
    content = MarkdownField(blank=True)
   
    search_fields = Page.search_fields + [
        index.SearchField('content'),
        index.SearchField('title'),
    ]

手动更新索引

./manage.py update_index

实际上如果你使用数据库作为搜索后端的话,Wagtail会自动绑定save/delete等信号去更新,因为我要给已有的内容建立索引,所以进行了手动操作。

如何搜索

当一切配置完毕之后,首先后台的搜索页面可以立刻看到效果。

其次,也可以在代码中使用搜索功能

q = request.GET.get('q')
BlogEntry.objects.search(q)

官方文档中提供了更丰富的功能说明,可以参考这里

可以看出,使用Wagtail的搜索系统可以很容易实现全文检索功能,它还有很多功能,我这里只是抛砖引玉,如果你想开发一个博客或者cms,Wagtail是个不错的选择。