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 RuntimeError: thread.__init__() not called解决方法
Apr 28 Python
详解Python多线程Selenium跨浏览器测试
Apr 01 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
Oct 29 Python
对python GUI实现完美进度条的示例详解
Dec 13 Python
Flask教程之重定向与错误处理实例分析
Aug 01 Python
详解centos7+django+python3+mysql+阿里云部署项目全流程
Nov 15 Python
python飞机大战pygame游戏之敌机出场实现方法详解
Dec 17 Python
Pytorch 多块GPU的使用详解
Dec 31 Python
Python restful框架接口开发实现
Apr 13 Python
python 下载文件的几种方式分享
Apr 07 Python
Python 多线程之threading 模块的使用
Apr 14 Python
python多次执行绘制条形图
Apr 20 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 array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
2020/02/03 PHP
jQuery extend 的简单实例
2013/09/18 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
JavaScript制作简单的日历效果
2016/03/10 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
jQuery实现发送验证码并60秒倒计时功能
2016/11/25 Javascript
jquery购物车结算功能实现方法
2020/10/29 Javascript
Angular JS数据的双向绑定详解及实例
2016/12/31 Javascript
jQuery实现倒计时重新发送短信验证码功能示例
2017/01/12 Javascript
Three.js利用顶点绘制立方体的方法详解
2017/09/27 Javascript
使用webpack3.0配置webpack-dev-server教程
2018/05/29 Javascript
vue中选项卡点击切换且能滑动切换功能的实现代码
2018/11/25 Javascript
layui表格 列自动适应大小失效的解决方法
2019/09/06 Javascript
Vue清除定时器setInterval优化方案分享
2020/07/21 Javascript
Python实现简单的获取图片爬虫功能示例
2017/07/12 Python
Python内置函数—vars的具体使用方法
2017/12/04 Python
Python的numpy库中将矩阵转换为列表等函数的方法
2018/04/04 Python
Python中fnmatch模块的使用详情
2018/11/30 Python
Django uwsgi Nginx 的生产环境部署详解
2019/02/02 Python
Python with用法:自动关闭文件进程
2019/07/10 Python
python实现的爬取电影下载链接功能示例
2019/08/26 Python
使用Keras中的ImageDataGenerator进行批次读图方式
2020/06/17 Python
python3 循环读取excel文件并写入json操作
2020/07/14 Python
aden + anais英国官网:美国婴儿贴身用品品牌
2019/09/08 全球购物
打架检讨书400字
2014/01/17 职场文书
综合实践活动总结
2014/05/05 职场文书
李培根演讲稿
2014/05/22 职场文书
中文专业求职信
2014/06/20 职场文书
单位委托书
2014/10/15 职场文书
国家助学金感谢信
2015/01/21 职场文书
我的中国梦主题教育活动总结
2015/05/07 职场文书
公司考勤管理制度
2015/08/04 职场文书
Pytorch 如何实现常用正则化
2021/05/27 Python