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 相关文章推荐
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
Nov 18 Python
Python实现Tab自动补全和历史命令管理的方法
Mar 12 Python
python 编程之twisted详解及简单实例
Jan 28 Python
Python编程实现蚁群算法详解
Nov 13 Python
Python实现判断字符串中包含某个字符的判断函数示例
Jan 08 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
Mar 22 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
Python paramiko模块使用解析(实现ssh)
Aug 30 Python
python numpy数组复制使用实例解析
Jan 10 Python
Python3爬虫关于识别点触点选验证码的实例讲解
Jul 30 Python
Requests什么的通通爬不了的Python超强反爬虫方案!
May 20 Python
Python 循环读取数据内存不足的解决方案
May 25 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 strtok()函数的优点分析
2010/03/02 PHP
php学习笔记 数组遍历实现代码
2011/06/09 PHP
PHP中其实也可以用方法链
2011/11/10 PHP
php5.3不能连接mssql数据库的解决方法
2014/12/27 PHP
php通过array_merge()函数合并关联和非关联数组的方法
2015/03/18 PHP
神奇的代码 通杀各种网站-可随意修改复制页面内容
2008/07/17 Javascript
jquery实现弹出窗口效果的实例代码
2013/11/28 Javascript
JS获取select的value和text值的简单实例
2014/02/26 Javascript
JavaScript实现同步于本地时间的动态时间显示方法
2015/02/02 Javascript
Ajax中解析Json的两种方法对比分析
2015/06/25 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
2015/08/11 Javascript
jQuery模拟实现天猫购物车动画效果实例代码
2017/05/25 jQuery
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
jQuery实现参数自定义的文字跑马灯效果
2018/08/15 jQuery
js使用swiper实现层叠轮播效果实例代码
2018/12/12 Javascript
[53:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第一场 1月31日
2021/03/11 DOTA
使用Python下载Bing图片(代码)
2013/11/07 Python
python制作小说爬虫实录
2017/08/14 Python
python机器人行走步数问题的解决
2018/01/29 Python
Django model序列化为json的方法示例
2018/10/16 Python
在Django下创建项目以及设置settings.py教程
2019/12/03 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
python由已知数组快速生成新数组的方法
2020/04/08 Python
Vs Code中8个好用的python 扩展插件
2020/10/12 Python
CheapTickets泰国:廉价航班,查看促销价格并预订机票
2019/12/28 全球购物
会计电算化应届生求职信
2013/11/03 职场文书
土木工程专业个人求职信
2013/12/30 职场文书
出国留学介绍信
2014/01/13 职场文书
在校大学生个人的自我评价
2014/02/13 职场文书
善意的谎言事例
2014/02/15 职场文书
应用数学专业求职信
2014/03/14 职场文书
2014年法务工作总结
2014/12/11 职场文书
培训班通知
2015/04/25 职场文书
通知的格式范文
2015/04/27 职场文书
Python基础知识学习之类的继承
2021/05/31 Python