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异常处理总结
Aug 15 Python
python使用any判断一个对象是否为空的方法
Nov 19 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
Nov 13 Python
解决Python出现_warn_unsafe_extraction问题的方法
Mar 24 Python
Python网络编程详解
Oct 31 Python
python 实现图片旋转 上下左右 180度旋转的示例
Jan 24 Python
Python3标准库总结
Feb 19 Python
基于Python执行dos命令并获取输出的结果
Dec 30 Python
Django项目uwsgi+Nginx保姆级部署教程实现
Apr 19 Python
使用Keras预训练好的模型进行目标类别预测详解
Jun 27 Python
Python Parser的用法
May 12 Python
使用pd.merge表连接出现多余行的问题解决
Jun 16 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
Smarty Foreach 使用说明
2010/03/23 PHP
PHP JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
php中运用http调用的GET和POST方法示例
2014/09/29 PHP
php实现点击可刷新验证码
2015/11/07 PHP
CakePHP框架Session设置方法分析
2017/02/23 PHP
js jquery做的图片连续滚动代码
2008/01/06 Javascript
JavaScript 设计模式学习 Factory
2009/07/29 Javascript
IE和Firefox的Javascript兼容性总结[推荐收藏]
2011/10/19 Javascript
学习从实践开始之jQuery插件开发 菜单插件开发
2012/05/03 Javascript
js正则表达式中test,exec,match方法的区别说明
2014/01/29 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
2015/11/29 Javascript
jquery限定文本框只能输入数字(整数和小数)
2016/01/08 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
JS中的二叉树遍历详解
2016/03/18 Javascript
JavaScript的Backbone.js框架入门学习指引
2016/05/07 Javascript
详解JavaScript跨域总结与解决办法
2016/10/31 Javascript
基于jQuery实现表格的排序
2016/12/02 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
Javascript柯里化实现原理及作用解析
2020/10/22 Javascript
[55:35]VGJ.S vs Mski Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
[33:17]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python3.2中Print函数用法实例详解
2015/05/19 Python
window下eclipse安装python插件教程
2017/04/24 Python
使用Python批量修改文件名的代码实例
2019/01/24 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
Python grpc超时机制代码示例
2020/09/14 Python
实例教程 纯CSS3打造非常炫的加载动画效果
2014/11/05 HTML / CSS
亚洲独特体验旅游专家:eOasia
2018/08/15 全球购物
如何定义一个可复用的服务
2014/09/30 面试题
体育专业个人的求职信范文
2013/09/21 职场文书
销售类个人求职信范文
2013/09/25 职场文书
2016幼儿园教师节新闻稿
2015/11/25 职场文书
分享一个vue实现的记事本功能案例
2022/04/11 Vue.js