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实现简单状态框架的方法
Mar 19 Python
使用Python保存网页上的图片或者保存页面为截图
Mar 05 Python
Python使用random.shuffle()打乱列表顺序的方法
Nov 08 Python
pycharm访问mysql数据库的方法步骤
Jun 18 Python
使用pip安装python库的多种方式
Jul 31 Python
Python使用enumerate获取迭代元素下标
Feb 03 Python
基于python3生成标签云代码解析
Feb 18 Python
python可迭代对象去重实例
May 15 Python
Python如何使用PIL Image制作GIF图片
May 16 Python
浅谈python出错时traceback的解读
Jul 15 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
Dec 31 Python
pytorch 实现在测试的时候启用dropout
May 27 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
给海燕B411配件机起死回生配上件
2021/03/02 无线电
在PHP中操作Excel实例代码
2010/04/29 PHP
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
配置php网页显示各种语法错误
2013/09/23 PHP
Linux系统下PHP-FPM的安装和配置教程
2015/08/17 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
PHP静态成员变量
2017/02/14 PHP
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
jquery更换文章内容与改变字体大小代码
2013/09/30 Javascript
Jquery 效果使用详解
2015/11/23 Javascript
Javascript字符串常用方法详解
2016/07/21 Javascript
AngularJs bootstrap详解及示例代码
2016/09/01 Javascript
JS实现拖拽的方法分析
2016/12/20 Javascript
JavaScript组件开发之输入框加候选框
2017/03/10 Javascript
vue.js事件处理器是什么
2017/03/20 Javascript
js禁止Backspace键使浏览器后退的实现方法
2017/09/01 Javascript
JavaScript中的高级函数
2018/01/04 Javascript
详解webpack编译速度提升之DllPlugin
2019/02/05 Javascript
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
python中lambda与def用法对比实例分析
2015/04/30 Python
python删除过期文件的方法
2015/05/29 Python
深入理解Python爬虫代理池服务
2018/02/28 Python
python爬取微信公众号文章
2018/08/31 Python
详解Python中is和==的区别
2019/03/21 Python
python在新的图片窗口显示图片(图像)的方法
2019/07/11 Python
pytorch中的inference使用实例
2020/02/20 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
python:删除离群值操作(每一行为一类数据)
2020/06/08 Python
《跨越百年的美丽》教学反思
2014/02/11 职场文书
文明倡议书范文
2014/04/15 职场文书
农林经济管理专业自荐信
2014/09/01 职场文书
2014年财政工作总结
2014/12/10 职场文书
美丽的大脚观后感
2015/06/03 职场文书
冰雪公主观后感
2015/06/16 职场文书
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫