Django中使用Whoosh进行全文检索的方法


Posted in Python onMarch 31, 2019

Whoosh 是纯Python实现的全文搜索引擎,通过Whoosh可以很方便的给文档加上全文索引功能。

什么是全文检索

简单讲分为两块,一块是分词,一块是搜索。比如下面一段话:

上次舞蹈演出直接在上海路的弄堂里

比如我们现在想检索上次的演出,通常我们会直接搜索关键词: 上次演出 ,但是使用传统的SQL like 查询并不能命中上面的这段话,因为在 上次 和 演出 中间还有 舞蹈 。然而全文搜索却将上文切成一个个Token,类似:

上次/舞蹈/演出/直接/在/上海路/的/弄堂/里

切分成Token后做反向索引(inverted indexing),这样我们就可以通过关键字很快查询到了结果了。

解决分词问题

分词是个很有技术难度的活,比如上面的语句中一个难点就是到底是 上海路 还是 上海 呢?Python有个中文分词库: 结巴分词 ,我们可以通过结巴分词来完成索引中分词工作,结巴分词提供了Whoosh的组件可以直接集成,代码示例

遇到的问题

如果是在一些VPS上测试的时候非常慢的话可能是内存不足,比如512MB做一个博客索引非常慢,尝试升级到1GB后可以正常使用了。

代码

import logging
import os
import shutil
from django.conf import settings

from whoosh.fields import Schema, ID, TEXT, NUMERIC
from whoosh.index import create_in, open_dir
from whoosh.qparser import MultifieldParser
from jieba.analyse import ChineseAnalyzer

from .models import Article

log = logging.getLogger(__name__)

index_dir = os.path.join(settings.BASE_DIR, "whoosh_index")

indexer = open_dir(index_dir)


def articles_search(keyword):

  mp = MultifieldParser(
    ['content', 'title'], schema=indexer.schema, fieldboosts={'title': 5.0})
  query = mp.parse(keyword)

  with indexer.searcher() as searcher:
    results = searcher.search(query, limit=15)

    articles = []
    for hit in results:
      log.debug(hit)
      articles.append({
        'id': hit['id'],
        'slug': hit['slug'],
      })

  return articles


def rebuild():
  if os.path.exists(index_dir):
    shutil.rmtree(index_dir)
  os.makedirs(index_dir)

  analyzer = ChineseAnalyzer()
  schema = Schema(
    id=ID(stored=True, unique=True),
    slug=TEXT(stored=True),
    title=TEXT(),
    content=TEXT(analyzer=analyzer))
  indexer = create_in(index_dir, schema)

  __index_all_articles()


def __index_all_articles():
  writer = indexer.writer()
  published_articles = Article.objects.exclude(is_draft=True)
  for article in published_articles:
    writer.add_document(
      id=str(article.id),
      slug=article.slug,
      title=article.title,
      content=article.content,
    )
  writer.commit()


def article_update_index(article):
  '''
  updating an article to indexer, adding if not.
  '''
  writer = indexer.writer()
  writer.update_document(
    id=str(article.id),
    slug=article.slug,
    title=article.title,
    content=article.content,
  )

  writer.commit()


def article_delete_index(article):
  writer = indexer.writer()
  writer.delete_by_term('id', str(article.id))

  writer.commit()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现获取序列中最小的几个元素
Sep 25 Python
Python写入CSV文件的方法
Jul 08 Python
Python常用时间操作总结【取得当前时间、时间函数、应用等】
May 11 Python
Python操作mysql数据库实现增删查改功能的方法
Jan 15 Python
python flask中静态文件的管理方法
Mar 20 Python
Python 绘图库 Matplotlib 入门教程
Apr 19 Python
python 获取键盘输入,同时有超时的功能示例
Nov 13 Python
Python面向对象之继承和多态用法分析
Jun 08 Python
Python unittest 自动识别并执行测试用例方式
Mar 09 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
Mar 30 Python
jupyter notebook实现显示行号
Apr 13 Python
python右对齐的实例方法
Jul 05 Python
Python实现的爬取小说爬虫功能示例
Mar 30 #Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
Mar 30 #Python
Python函数装饰器常见使用方法实例详解
Mar 30 #Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
Mar 30 #Python
Python函数的参数常见分类与用法实例详解
Mar 30 #Python
Python实现定时执行任务的三种方式简单示例
Mar 30 #Python
详解Python解决抓取内容乱码问题(decode和encode解码)
Mar 29 #Python
You might like
杏林同学录(五)
2006/10/09 PHP
php连接微软MSSQL(sql server)完全攻略
2016/11/27 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
Ucren Virtual Desktop V2.0
2006/11/07 Javascript
JavaScript面向对象之体会[总结]
2008/11/13 Javascript
Prototype源码浅析 String部分(四)之补充
2012/01/16 Javascript
ExtJs纵坐标值重复问题的解决方法
2014/02/27 Javascript
JavaScript多图片上传案例
2015/09/28 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
2016/05/30 Javascript
使用JS中的exec()方法构造正则表达式验证
2016/08/01 Javascript
jQuery ztree实现动态树形多选菜单
2016/08/12 Javascript
简单理解js的冒泡排序
2016/12/19 Javascript
微信小程序 slider 详解及实例代码
2017/01/10 Javascript
js 用于检测类数组对象的函数方法
2017/05/02 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
2018/05/15 Javascript
浅谈node中的cluster集群
2018/06/02 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
微信小程序一周时间表功能实现
2019/10/17 Javascript
浅析JS中NEW的实现原理及重写
2020/02/20 Javascript
[04:16]DOTA2英雄梦之声_第09期_斧王
2014/06/21 DOTA
[06:33]DOTA2亚洲邀请赛小组赛第二日 TOP10精彩集锦
2015/01/31 DOTA
一个简单的python程序实例(通讯录)
2013/11/29 Python
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
python从入门到精通(DAY 3)
2015/12/20 Python
打包发布Python模块的方法详解
2016/09/18 Python
python实现多张图片拼接成大图
2019/01/15 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
python中urllib.request和requests的使用及区别详解
2020/05/05 Python
Python中Yield的基本用法
2020/10/18 Python
房屋所有权证明
2014/10/20 职场文书
小学班主任评语
2014/12/29 职场文书
2015中秋节晚会主持词
2015/07/01 职场文书
创业项目(超低成本创业项目)
2019/08/16 职场文书
关于PostgreSQL JSONB的匹配和交集问题
2021/09/14 PostgreSQL
Oracle 多表查询基本语法实例
2022/04/18 Oracle