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 k-近邻算法实例分享
Jun 11 Python
python3 pillow生成简单验证码图片的示例
Sep 19 Python
python机器学习理论与实战(四)逻辑回归
Jan 19 Python
Python爬虫框架Scrapy实例代码
Mar 04 Python
使用Python从零开始撸一个区块链
Mar 14 Python
python3实现名片管理系统
Nov 29 Python
python使用udp实现聊天器功能
Dec 10 Python
windows下Python安装、使用教程和Notepad++的使用教程
Oct 06 Python
python 求10个数的平均数实例
Dec 16 Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
Jun 04 Python
python为什么会环境变量设置不成功
Jun 23 Python
python 利用opencv实现图像网络传输
Nov 12 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程序
2012/02/04 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
2012/07/16 PHP
PHP5下$_SERVER变量不再受magic_quotes_gpc保护的弥补方法
2012/10/31 PHP
详解HTTP Cookie状态管理机制
2016/01/14 PHP
PHP中的use关键字及文件的加载详解
2016/11/28 PHP
php图片裁剪函数
2018/10/31 PHP
详解PHP的抽象类和抽象方法以及接口总结
2019/03/15 PHP
Laravel框架文件上传功能实现方法示例
2019/04/16 PHP
html读出文本文件内容
2007/01/22 Javascript
Javascript获取当前日期的农历日期代码
2014/10/08 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
jQuery使用Layer弹出层插件闪退问题
2016/12/22 Javascript
js上下视差滚动简单实现代码
2017/03/07 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
JavaScript实现提交模式窗口后刷新父窗口数据的方法
2017/06/16 Javascript
vue.js评论发布信息可插入QQ表情功能
2017/08/08 Javascript
vue 粒子特效的示例代码
2017/09/19 Javascript
vue基于Element构建自定义树的示例代码
2017/09/19 Javascript
Element Input组件分析小结
2018/10/11 Javascript
使用vue开发移动端管理后台的注意事项
2019/03/07 Javascript
基于layPage插件实现两种分页方式浅析
2019/07/27 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
JS继承实现方法及优缺点详解
2020/09/02 Javascript
python如何实现excel数据添加到mongodb
2015/07/30 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
Python将list中的string批量转化成int/float的方法
2018/06/26 Python
Python pymongo模块常用操作分析
2018/09/01 Python
python实现Zabbix-API监控
2018/09/17 Python
热爱祖国演讲稿
2014/05/04 职场文书
宿舍标语大全
2014/06/19 职场文书
大学课外活动总结
2014/07/09 职场文书
地理信息科学专业推荐信
2014/09/08 职场文书
2014年纪检工作总结
2014/11/12 职场文书
python执行js代码的方法
2021/05/13 Python
Win11怎么进入安全模式?Windows 11进入安全模式的方法
2021/11/21 数码科技