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 相关文章推荐
在Django的模板中使用认证数据的方法
Jul 23 Python
python通过文件头判断文件类型
Oct 30 Python
python 调用HBase的简单实例
Dec 18 Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
May 21 Python
python文件操作之批量修改文件后缀名的方法
Aug 10 Python
python 使用sys.stdin和fileinput读入标准输入的方法
Oct 17 Python
浅谈python中拼接路径os.path.join斜杠的问题
Oct 23 Python
python判断文件是否存在,不存在就创建一个的实例
Feb 18 Python
PyQt5实现让QScrollArea支持鼠标拖动的操作方法
Jun 19 Python
Django model select的多种用法详解
Jul 16 Python
Python FtpLib模块应用操作详解
Dec 12 Python
Python操作Elasticsearch处理timeout超时
Jul 17 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
国王的咖啡这么大来头,名字的由来是什么
2021/03/03 咖啡文化
PHP提高编程效率的20个要点
2015/09/23 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
JavaScript传递变量: 值传递?引用传递?
2011/02/22 Javascript
兼容IE和Firefox火狐的上下、左右循环无间断滚动JS代码
2013/04/19 Javascript
JS无限极树形菜单,json格式、数组格式通用示例
2013/07/30 Javascript
JS的location.href跳出框架打开新页面的方法
2014/09/04 Javascript
JS实现网页滚动条感应鼠标变色的方法
2015/02/26 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
2015/03/02 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
浅析jQuery 遍历函数,javascript中的each遍历
2016/05/25 Javascript
javascript实现复选框全选或反选
2017/02/04 Javascript
vue动态生成dom并且自动绑定事件
2017/04/19 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
jquery实现下拉菜单的手风琴效果
2017/07/23 jQuery
基于js中document.cookie全面解析
2017/09/14 Javascript
Vue keepAlive 数据缓存工具实现返回上一个页面浏览的位置
2019/05/10 Javascript
JS正则表达式封装与使用操作示例
2019/05/15 Javascript
在vue中配置不同的代理同时访问不同的后台操作
2020/09/11 Javascript
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
Python模拟随机游走图形效果示例
2018/02/06 Python
转换科学计数法的数值字符串为decimal类型的方法
2018/07/16 Python
使用Python脚本zabbix自定义key监控oracle连接状态
2019/08/28 Python
python如何通过闭包实现计算器的功能
2020/02/22 Python
Python获取浏览器窗口句柄过程解析
2020/07/25 Python
详解Python中import机制
2020/09/11 Python
基础的CSS3弹性盒Flexbox布局使用实例
2016/04/08 HTML / CSS
Onzie官网:美国时尚瑜伽品牌
2019/08/21 全球购物
创业计划书中要认真思考的问题
2013/12/28 职场文书
承诺函格式模板
2015/01/21 职场文书
违纪检讨书
2015/01/27 职场文书
2019银行竞聘书
2019/06/21 职场文书
详解Python描述符的工作原理
2021/06/11 Python
《游戏王:大师决斗》新活动上线 若无符合卡组可免费租用
2022/04/13 其他游戏