Django中使用Whoosh进行全文检索的方法

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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • python django使用haystack:全文检索的框架(实例讲解)

    haystack:全文检索的框架 whoosh:纯Python编写的全文搜索引擎 jieba:一款免费的中文分词包 首先安装这三个包 pip install django-haystack pip install whoosh pip install jieba 1.修改settings.py文件,安装应用haystack, 2.在settings.py文件中配置搜索引擎 HAYSTACK_CONNECTIONS = { 'default': { # 使用whoosh引擎 'ENGINE': '

  • Python中使用haystack实现django全文检索搜索引擎功能

    前言 django是python语言的一个web框架,功能强大.配合一些插件可为web网站很方便地添加搜索功能. 搜索引擎使用whoosh,是一个纯python实现的全文搜索引擎,小巧简单. 中文搜索需要进行中文分词,使用jieba. 直接在django项目中使用whoosh需要关注一些基础细节问题,而通过haystack这一搜索框架,可以方便地在django中直接添加搜索功能,无需关注索引建立.搜索解析等细节问题. haystack支持多种搜索引擎,不仅仅是whoosh,使用solr.elas

  • Django实现全文检索的方法(支持中文)

    PS: 我的检索是在文章模块下 forum/article 第一步:先安装需要的包: pip install django-haystack pip install whoosh pip install jieba 第二步: 配置需要的文件 settings.py 添加haystack应用模块 INSTALLED_APPS = ( ... 'haystack', ... ) 在settings.py 末尾添加 HAYSTACK_CONNECTIONS = { 'default': { 'ENGI

  • Django中使用Whoosh进行全文检索的方法

    Whoosh 是纯Python实现的全文搜索引擎,通过Whoosh可以很方便的给文档加上全文索引功能. 什么是全文检索 简单讲分为两块,一块是分词,一块是搜索.比如下面一段话: 上次舞蹈演出直接在上海路的弄堂里 比如我们现在想检索上次的演出,通常我们会直接搜索关键词: 上次演出 ,但是使用传统的SQL like 查询并不能命中上面的这段话,因为在 上次 和 演出 中间还有 舞蹈 .然而全文搜索却将上文切成一个个Token,类似: 上次/舞蹈/演出/直接/在/上海路/的/弄堂/里 切分成Token

  • Django中url的反向查询的方法

    本文介绍了Django中url的反向查询的方法,分享给大家,具体如下: 明确几个概念: 1.application namespace : 正在部署的app的名称,一个app的多个实例应该具有相同的application namespace. 可以通过在URLconf模块(urls.py)中设置 app_name 属性(与urlpatterns属性同级)来指定application namesapce. (在django2.0版本中必须设置 app_name ) 2.instance names

  • django中模板的html自动转意方法

    一.需求来源: 如果用户在文本框中填了一段<script>alert(xxx);</script>代码,然后我们还保存在了数据库中,下次模板加载数据的时候,将这段代码显示在浏览器,将会弹出一个警告框.因此,这是XSS(跨域脚本)攻击的一种方式,我们肯定不能允许这种事件发生,因此django默认给我们启动了自动转意的功能.将这段代码转换成普通的文本进行展示. 二.如何关闭: 你肯定会问既然自动转意可以关闭XSS漏洞为什么需要关闭呢?原因很简单,如果你数据库中保存了一段可信任的HTML

  • 浅谈Django中view对数据库的调用方法

    question: Django中对数据库的调用非常的隐蔽,在各种复杂的模块互相拼接继承中很难发现获取数据库内容的部分 来,开始试图理解一下下 首先,数据库中的表对应的是model中的每一个类,类中的变量对应表的属性,通常属性名就是变量名.有一个比较特殊的东西就是ForeignKey,它代表了与其他表的关联约束键,即SQL中的约束键,通常和其他表中的主键primary key相关联. 理解了model是我们定义的数据表,接下来的事情就会越发的简单,我们都知道网页中的data信息是通过Django

  • 在django中,关于session的通用设置方法

    最近发现session的知识有点脱节了,默认设置愣是搞半天,看来忘了不少.今天把一些通用设置贴上来,以备随时回顾. 配置文件中设置默认操作(通用配置): SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN

  • 在Django中输出matplotlib生成的图片方法

    下面的代码片段是直接在Django中输出matplotlib生成的图片,网上很多种方法都是先生成图片再调用,感觉不是那么直接. 环境:Python2.7,Django1.83 该文件为views.py文件,函数映射按实际设置. from django.shortcuts import render from django.http import HttpResponse from matplotlib.figure import Figure from matplotlib.backends.b

  • Django中Aggregation聚合的基本使用方法

    Django 的 filter.exclude 等方法使得对数据库的查询很方便了.这在数据量较小的时候还不错,但如果数据量很大,或者查询条件比较复杂,那么查询效率就会很低. 提高数据库查询效率可以通过原生 SQL 语句来实现,但是它的缺点就是需要开发者熟练掌握 SQL.倘若查询条件是动态变化的,则编写 SQL 会更加困难. 对于以便捷著称的 Django,怎么能忍受这样的事.于是就有了 Aggregation聚合 . 聚合最好的例子就是官网给的案例了: # models.py from djan

  • django中使用原生sql语句的方法步骤

    raw # row方法:(掺杂着原生sql和orm来执行的操作) res = CookBook.objects.raw('select id as nid from epos_cookbook where id>%s', params=[1, ]) print(res.columns) # ['nid'] print(type(res)) # <class 'django.db.models.query.RawQuerySet'> # 在select里面查询到的数据orm里面的要一一对应

  • Django中信号signals的简单使用方法

    正文 在平时的开发过程中,我们会遇到一些特殊的应用场景,如果你想要在执行某种操作之前或者之后你能够得到通知,并对其进行一些你想要的操作时,你就可以用Django中的信号(signals).Django 提供一个"信号分发器",允许解耦的应用在框架的其它地方发生操作时会被通知到,也就是说在特定事件发生时,可以发送一个信号去通知所有注册了这个信号的回调,在回调里进行想要的操作处理. 一.Django内置信号 Django内置了对数据表,migrate命令,url请求相关(request/r

  • django中静态文件配置static的方法

    环境 centos7 django 1.11 nginx 白话 我们可以使用Template 设置我们的网页,同时,一个完美的网页需要css,js,image 等静态文件的支持. django中配置方式貌似有不少总,因为很多相关的博客写的方式并不一致,当然这可能是django 的版本不同导致的. 当我们在一个项目下创建一个app后,我们就需要为该app下创建一个static 文件夹来存放相关静态资源. 但创建了多个app后,就需要在多个app下创建static. 这样引入了一个问题,因为,我们的

随机推荐