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多线程编程中的join函数使用心得
Sep 02 Python
在Python的Django框架中用流响应生成CSV文件的教程
May 02 Python
python使用in操作符时元组和数组的区别分析
May 19 Python
详解Python数据可视化编程 - 词云生成并保存(jieba+WordCloud)
Mar 26 Python
Django使用redis缓存服务器的实现代码示例
Apr 28 Python
python实现坦克大战游戏 附详细注释
Mar 27 Python
Python3 JSON编码解码方法详解
Sep 06 Python
Python zip函数打包元素实例解析
Dec 11 Python
Python中bisect的使用方法
Dec 31 Python
pycharm工具连接mysql数据库失败问题
Apr 01 Python
python 安装移动复制第三方库操作
Jul 13 Python
matplotlib对象拾取事件处理的实现
Jan 14 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/02/27 无线电
使用cookie实现统计访问者登陆次数
2013/06/08 PHP
PHP使用CURL实现对带有验证码的网站进行模拟登录的方法
2014/07/23 PHP
PHP面向对象之后期静态绑定功能介绍
2015/05/18 PHP
php数组函数array_key_exists()小结
2015/12/10 PHP
php提交post数组参数实例分析
2015/12/17 PHP
PHP读取大文件末尾N行的高效方法推荐
2016/06/03 PHP
PHP实现打包下载文件的方法示例
2017/10/07 PHP
用javascript父窗口控制只弹出一个子窗口
2007/04/10 Javascript
Javascript 面向对象 重载
2010/05/13 Javascript
jQuery 对Select的操作备忘记录
2011/07/04 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
JavaScript中instanceof运算符的用法总结
2013/11/19 Javascript
js类式继承与原型式继承详解
2016/04/07 Javascript
轻松实现jQuery添加删除按钮Click事件
2017/03/13 Javascript
jQuery实现动态删除LI的方法
2017/05/30 jQuery
自定义vue全局组件use使用、vuex的使用详解
2017/06/14 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
2017/06/22 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
2019/11/13 Javascript
jQuery实现获取多选框的值示例
2020/02/07 jQuery
[02:05]2014DOTA2西雅图邀请赛 专访啸天mik夫妻档
2014/07/08 DOTA
python静态方法实例
2015/01/14 Python
Python连接PostgreSQL数据库的方法
2016/11/28 Python
Python中工作日类库Busines Holiday的介绍与使用
2017/07/06 Python
Python PyQt4实现QQ抽屉效果
2018/04/20 Python
利用Python函数实现一个万历表完整示例
2021/01/23 Python
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
浅谈HTML5 & CSS3的新交互特性
2016/07/19 HTML / CSS
彪马土耳其官网:PUMA土耳其
2019/07/14 全球购物
扬尘污染防治方案
2014/06/15 职场文书
镇政府副镇长群众路线专题民主生活会对照检查材料
2014/09/19 职场文书
2014大学生学生会工作总结
2014/12/19 职场文书
2015感人爱情寄语
2015/02/26 职场文书
小学生暑假生活总结
2015/07/13 职场文书
阳光体育运动标语口号
2015/12/26 职场文书