Django--全文检索功能
经过两个月的时间,毕设终于算是把所有主要功能都完成了,最近这一周为了实现全文检索的功能,也算是查阅了不少资料,今天就在这里记录一下,以免以后再用到时抓瞎了~
首先介绍一下我使用的Django全文检索逻辑了,在网上查看了各种资料发现,Django上一般用到的检索引擎基本上就是whoosh,sphinx,xapian了。后面的sphinx,xapian大家都可以在百度百科上找到相应的词条,基本都是使用了很大的项目使用的,毕竟是基于C写的,效率上肯定不必多言了,但是我这个杀鸡的活还用不到这两把牛刀了,这次我使用的是第一个whoosh引擎了,为什么使用这个呢?
因为whoosh是一个纯python实现的全文搜索组件。
主要特性
- 敏捷的API(Pythonic API)。
- 纯python实现,无二进制包。程序不会莫名其妙的崩溃。
- 按字段进行索引。
- 索引和搜索都非常的快 -- 是目前最快的纯python全文搜索引擎。
- 良好的构架,评分模块/分词模块/存储模块等各个模块都是可插拔的。
- 功能强大的查询语言(通过pyparsing实现功能)。
- 纯python实现的拼写检查(目前唯一的纯python拼写检查实现)
其实对我来说最重要的还是源于它的易用性和简单,毕竟对于毕业设计来说,需要的时间复杂度还是很重要的"ㄟ( ▔, ▔ )ㄏ"
那么接下来就是分词了~如果把用户输入的内容全部拿去检索那不就和数据库的模糊查询一个意思了嘛~所以我需要一个能分词的工具,但是whoosh的内部是使用正则来分词的,虽然这在英文的世界里理所应当,但是毕竟我主要是用来检索中文的,所以必须要有一个靠得住的中文分词库,而中文分词要达到智能、准确并不是一件容易的事,目前国内有不少商业的分词库。当然了,也有一些免费的中文分词库可以使用,比如我使用的这个“jieba”分词库,而且他们号称是“做最好的 Python 中文分词组件”,这是他们的GitHub地址。
好了,现在检索引擎和分词库都有了,那么接下来就是如何将这两个整合到我们的项目中了~下面出场的就是今天的主角了~django-haystack,这个一款同时支持whoosh,solr,Xapian,Elasticsearc四种全文检索引擎的第三方app,这意味着如果你不想使用whoosh,那你随时可以将之更换成Xapian等其他搜索引擎,而不用更改代码。正如Django一样,Django-haystack的使用也非常简单。
现在我们该把他们整合到一起了,首先,先把他们都安装上吧
pip install whoosh
pip install jieba
pip install django-haystack
然后我们在app目录下建立一个search_indexes.py,代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2015-05-07 14:15:13
# @Author : jonnyF (fuhuixiang@jonnyf.com)
# @Link : http://jonnyf.com from dlnubuy.models import Product
from haystack import indexes class ProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) # 对pdname和description字段进行索引
pdname = indexes.CharField(model_attr='pdname') description = indexes.CharField(model_attr='description') def get_model(self):
return Product def index_queryset(self, using=None):
return self.get_model().objects.all()
这里要注意的是文件名称必须是search_indexes.py,否则会报错的!!!
然后在模板目录下面建立templates/search/indexes/<appname>/product_text.txt,这个模板的作用是让text字段包含的内容,在后面的模板中可能会有用。
然后在settings.py里面配置:
# full text search
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'dlnubuy.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
# 自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
这样我们的检索引擎,分词器都连在一起了,但是要主要的一点是,我们现在的检索引擎依旧使用的是自身的分词器,而不是我们的jieba,所以接下来就是把他俩和在一起了,要注意的是我这里以及对whoosh的检索引擎修改过了,所以为了方便移植,所以我将whoosh的检索引擎放在了我app的目录下面,这样就不再依赖本机的环境了。
首先先将../Python27/Lib/site-packages/haystack/backends目录中的whoosh_backend.py文件复制到app目录下并改名为whoosh_cn_backend.py,这个文件名要和setting文件中配置中的一样,当然,我们不是全部都修改这个文件,修改的仅仅是期中的个别位置,修改的地方如下:
#在全局引入的最后一行加入jieba分词器
from jieba.analyse import ChineseAnalyzer #修改
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),
field_boost=field_class.boost, sortable=True)
之后是重建索引:python manage.py rebuild_index 这样修改完成之后就可以使用了,关于自动更新索引这件事来说,我觉得并没有必要在每次修改数据库的时候都更新,所以后来改为了只有修改我检索的字段的时候才使用manage.py update_index 更新索引。
接下来就是在搜索框提交之后来处理的后台逻辑了:
# 全局搜索
def full_search(request):
sform = SearchForm(request.GET)
posts = sform.search()
template = 'product_search_list.html'
c = Context({'posts': posts})
return render_to_response(template, c)
由于我使用的是模板来渲染的显示页面,所以在这个我就不贴出代码来了(太简单了,没什么要注意的),主要就是在模板中使用循环来遍历posts变量,而这个变量的类型是SearchResult的,这里就简单的列举一下SearchResult的一些参数了:
Attribute Reference
The class exposes the following useful attributes/properties: app_label - The application the model is attached to.
model_name - The model’s name.
pk - The primary key of the model.
score - The score provided by the search engine.
object - The actual model instance (lazy loaded).
model - The model class.
verbose_name - A prettier version of the model’s class name for display.
verbose_name_plural - A prettier version of the model’s plural class name for display.
searchindex - Returns the SearchIndex class associated with this result.
distance - On geo-spatial queries, this returns a Distance object representing the distance the result was from the focused point.
这里我使用的是object,然后通过{{i.object.description}}这样的模板来显示细节的,其他的地方就是具体项目具体细节咯~
以上便是我实现全文检索的全部流程和逻辑,需要注意的是haystack的1.X版本和2.X版本在自动更新处还是有很大不同的,有些资料参考的时候还是要注意一下的(更新细节),今天在这里记录下来,以免遗忘。by-JonnyF
Django--全文检索功能的更多相关文章
- Django:全文检索功能可参考博客
https://blog.csdn.net/AC_hell/article/details/52875927 https://www.zmrenwu.com/courses/django-blog-t ...
- Django 分页功能
Django 分页功能比较强大,这边是结合官网的内容写的可以参考 https://docs.djangoproject.com/en/1.9/topics/pagination/ 分页命令行练习案列 ...
- 使用Lucene对doc、docx、pdf、txt文档进行全文检索功能的实现
转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/76273859 本文出自[我是干勾鱼的博客] 这里讲一下使用Lucene对doc. ...
- Django——分页功能Paginator
Django分页功能----Paginator Paginator所需参数: Paginator(object_list,per_page) Paginator常用属性: per_page: 每页显示 ...
- 在ef core中使用postgres数据库的全文检索功能实战
起源 之前做的很多项目都使用solr/elasticsearch作为全文检索引擎,它们功能全面而强大,但是对于较小的项目而言,构建和维护成本显然过高,尤其是从关系数据库/文档数据库到全文检索引擎的数据 ...
- 使用haystack实现django全文检索搜索引擎功能
前言 django是python语言的一个web框架,功能强大.配合一些插件可为web网站很方便地添加搜索功能. 搜索引擎使用whoosh,是一个纯python实现的全文搜索引擎,小巧简单. 中文搜索 ...
- sphinx全文检索功能 | windows下测试 (一)
前一阵子尝试使用了一下Sphinx,一个能够被各种语言(PHP/Python/Ruby/etc)方便调用的全文检索系统.网上的资料大多是在linux环境下的安装使用,当然,作为生产环境很有必要部署在* ...
- django全文检索
-------------------linux下配置操作1.在虚拟环境中依次安装包 1.pip install django-haystack haystack:django的一个包,可以方便地对m ...
- Django—常用功能
索引 一.静态文件 二.中间件 三.Admin站点 3.1 列表页选项 3.2 编辑页选项 3.3 重写模板 四.上传图片 4.1 在管理页面admin中上传图片 4.2 自定义form表单中上传图片 ...
- django分页功能实现
django内置的分页功能需要引入内置模块from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger Pagina ...
随机推荐
- 《jQuery知识点总结》(一)
write less do more写更少的代码实现更多的功能DOM:document object model (文件对象模型)选择器(选择元素的对象或者节点)id 选择器 $("#id& ...
- Unity MonoDevelop一打开未响应
在学习Untiy的时候,使用内置的MonoDevelop开发工具.本来就不好用,经常出现未响应的情况,然后重启解决.终于有一次莫名其妙的崩溃了,在Unity打开该IDE就未响应,但直接打开MonoDe ...
- tcp_tw_reuse、tcp_tw_recycle 使用场景及注意事项
linux TIME_WAIT 相关参数: net.ipv4.tcp_tw_reuse = 表示开启重用.允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 net.i ...
- Docker - 技术栈
与传统的方式类似,构建及运行Docker容器与在一台虚拟机上构建和运行程序的方式是相似的,只是使用了一套新的工具以及技术. 与虚拟机不同的是,Docker容器将宿主机与应用程序或者服务隔离,从而提高了 ...
- office 365 Sharepoint 2013
平台环境: office 365 Sharepoint 2013 操作文件和文件夹 访问文档库的最佳方式是借助在 /_api/web 处可用的 GetFolderByServerRelativeUr ...
- ASCII码、Unicode码 转中文
ASCII码.Unicode码 转中文 在最近工作中遇到了一些汉字编码转换的处理,可以通过正则表达式及转换字符来实现转成中文 Unicode转换示例 通常为10位编码, 通过digit参数传入 pri ...
- MFC序列化与反序列化
#pragma once #include "afx.h" #include <vector> using std::vector; class HzyData : p ...
- java模拟浏览器上传文件
public static void main(String[] args) { String str = uploadFile("C:/Users/RGKY/Desktop/wKgBHVb ...
- jsonp是什么【转载自JavaScript微信公众号】
转自 http://mp.weixin.qq.com/s/xNnKAeLv6sO0T-IvP2AUlQ JavaScript微信公众号 一.JSONP的诞生 首先,因为ajax无法跨 ...
- *使用while循环遍历数组创建索引和自增索引值
package com.chongrui.test;/* *使用while循环遍历数组 * * * */public class test { public static void main ...