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 28 Python
Python获取指定文件夹下的文件名的方法
Feb 06 Python
Python基于property实现类的特性操作示例
Jun 15 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
Jun 21 Python
Python爬取成语接龙类网站
Oct 19 Python
python绘制散点图并标记序号的方法
Dec 11 Python
celery4+django2定时任务的实现代码
Dec 23 Python
python做接口测试的必要性
Nov 20 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
Jan 23 Python
使用python matploblib库绘制准确率,损失率折线图
Jun 16 Python
Python GUI之tkinter窗口视窗教程大集合(推荐)
Oct 20 Python
PyCharm 安装与使用配置教程(windows,mac通用)
May 12 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
php实现utf-8和GB2312编码相互转换函数代码
2013/02/07 PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
2014/05/23 PHP
Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法
2016/03/29 PHP
jquery 动态创建元素的方式介绍及应用
2013/04/21 Javascript
javascript实现2048游戏示例
2014/05/04 Javascript
jQuery使用contains过滤器实现精确匹配方法详解
2016/02/25 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
JS常用函数和常用技巧小结
2016/10/15 Javascript
js实现功能比较全面的全选和多选
2017/03/02 Javascript
Django1.7+JQuery+Ajax验证用户注册集成小例子
2017/04/08 jQuery
网页中的图片查看器viewjs使用方法
2017/07/11 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
利用vue.js把静态json绑定bootstrap的table方法
2018/08/28 Javascript
微信小程序之swiper滑动面板用法示例
2018/12/04 Javascript
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
[55:44]OG vs NAVI 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
用map函数来完成Python并行任务的简单示例
2015/04/02 Python
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
Windows下使Python2.x版本的解释器与3.x共存的方法
2015/10/25 Python
让python在hadoop上跑起来
2016/01/27 Python
python向字符串中添加元素的实例方法
2019/06/28 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
python圣诞树编写实例详解
2020/02/13 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
详解python with 上下文管理器
2020/09/02 Python
如何用tempfile库创建python进程中的临时文件
2021/01/28 Python
html5使用canvas绘制太阳系效果
2014/12/15 HTML / CSS
书香校园活动方案
2014/02/28 职场文书
热爱祖国演讲稿
2014/05/04 职场文书
政府法律服务方案
2014/06/14 职场文书
教师师德师风整改措施
2014/10/24 职场文书
护士辞职信怎么写
2015/02/27 职场文书
会计专业自荐信范文
2015/03/05 职场文书
教务处干事工作总结
2015/08/14 职场文书
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js