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 输出一个两行字符的变量
Feb 05 Python
python的re模块应用实例
Sep 26 Python
python调用java模块SmartXLS和jpype修改excel文件的方法
Apr 28 Python
Python 制作糗事百科爬虫实例
Sep 22 Python
python使用knn实现特征向量分类
Dec 26 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
May 09 Python
搞清楚 Python traceback的具体使用方法
May 13 Python
解决IDEA 的 plugins 搜不到任何的插件问题
May 04 Python
pycharm设置默认的UTF-8编码模式的方法详解
Jun 01 Python
利用Python实现Json序列化库的方法步骤
Sep 09 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
Feb 25 Python
Python基础之进程详解
May 21 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伪静态的实现详细介绍
2013/04/28 PHP
PHP中PDO连接数据库中各种DNS设置方法小结
2016/05/13 PHP
自用js开发框架小成 学习js的朋友可以看看
2010/11/16 Javascript
SOSO地图API使用(一)在地图上画圆实现思路与代码
2013/01/15 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
2015/11/15 Javascript
基于html5和nodejs相结合实现websocket即使通讯
2015/11/19 NodeJs
jQuery对html元素的取值与赋值实例详解
2015/12/18 Javascript
vue.js入门教程之绑定class和style样式
2016/09/02 Javascript
微信小程序 Storage API实例详解
2016/10/02 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
网页爬虫之cookie自动获取及过期自动更新的实现方法
2018/03/06 Javascript
独立部署小程序基于nodejs的服务器过程详解
2019/06/24 NodeJs
如何在微信小程序中存setStorage
2019/12/13 Javascript
Angular短信模板校验代码
2020/09/23 Javascript
[06:23]2014DOTA2西雅图国际邀请赛 小组赛7月12日TOPPLAY
2014/07/12 DOTA
[37:23]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#2Secret VS EG第二局
2016/03/04 DOTA
进一步探究Python中的正则表达式
2015/04/28 Python
使用Python的toolz库开始函数式编程的方法
2018/11/15 Python
python 实现矩阵上下/左右翻转,转置的示例
2019/01/23 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
2019/06/13 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
Python利用PyExecJS库执行JS函数的案例分析
2019/12/18 Python
AmazeUI 网格的实现示例
2020/08/13 HTML / CSS
世界上最大的冷却器制造商:Igloo Coolers
2019/07/23 全球购物
英语道歉信范文
2014/01/09 职场文书
小小的船教学反思
2014/02/21 职场文书
党员干部承诺书范文
2014/03/25 职场文书
先进单位事迹材料
2014/12/25 职场文书
党风廉政承诺书2016
2016/03/25 职场文书
Nest.js参数校验和自定义返回数据格式详解
2021/03/29 Javascript
用几道面试题来看JavaScript执行机制
2021/04/30 Javascript
探讨Java中的深浅拷贝问题
2021/06/26 Java/Android
css布局巧妙技巧之css三角示例的运用
2022/03/16 HTML / CSS
解决Windows Server2012 R2 无法安装 .NET Framework 3.5
2022/04/29 Servers