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中运算符使用时的优先级
May 14 Python
python实现爬虫统计学校BBS男女比例之数据处理(三)
Dec 31 Python
python机器学习实战之K均值聚类
Dec 20 Python
CentOS下Python3的安装及创建虚拟环境的方法
Nov 28 Python
Django框架实现的普通登录案例【使用POST方法】
May 15 Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 Python
使用Python完成15位18位身份证的互转功能
Nov 06 Python
Python之Matplotlib文字与注释的使用方法
Jun 18 Python
python里glob模块知识点总结
Jan 05 Python
matlab xlabel位置的设置方式
May 21 Python
Python答题卡识别并给出分数的实现代码
Jun 22 Python
基于Python实现股票收益率分析
Apr 02 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中关于foreach使用引用变量的坑
2016/11/14 PHP
详解php中serialize()和unserialize()函数
2017/07/08 PHP
JavaScript 对话框和状态栏使用说明
2009/10/25 Javascript
JavaScript 字符串处理函数使用小结
2010/12/02 Javascript
js 字符串转化成数字的代码
2011/06/29 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
easyui form validate总是返回false的原因及解决方法
2016/11/07 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
vue-auto-focus: 控制自动聚焦行为的 vue 指令方法
2018/08/25 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
Element Notification通知的实现示例
2020/07/27 Javascript
跟老齐学Python之集成开发环境(IDE)
2014/09/12 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
利用Python如何将数据写到CSV文件中
2018/06/05 Python
python中的不可变数据类型与可变数据类型详解
2018/09/16 Python
基于python3 的百度图片下载器的实现代码
2019/11/05 Python
Django3.0 异步通信初体验(小结)
2019/12/04 Python
Python实现计算长方形面积(带参数函数demo)
2020/01/18 Python
Python3 元组tuple入门基础
2020/02/09 Python
Python实现鼠标自动在屏幕上随机移动功能
2020/03/14 Python
利用python生成照片墙的示例代码
2020/04/09 Python
升级keras解决load_weights()中的未定义skip_mismatch关键字问题
2020/06/12 Python
Html5移动端弹幕动画实现示例代码
2018/08/27 HTML / CSS
美国名牌香水折扣网站:Hottperfume
2021/02/10 全球购物
一套中级Java程序员笔试题
2015/01/14 面试题
工程管理英文求职信
2014/03/18 职场文书
剪彩仪式主持词
2014/03/19 职场文书
贷款委托书怎么写
2014/08/02 职场文书
机械工程及其自动化专业求职信
2014/08/08 职场文书
夫妻忠诚协议范文
2014/11/16 职场文书
2014年单位工作总结范文
2014/11/27 职场文书
求职简历自我评价范文
2015/03/10 职场文书
工伤认定行政答辩状
2015/05/22 职场文书
小学数学国培研修日志
2015/11/13 职场文书