django使用全文索引

9 篇文章 0 订阅

前言

最近在学习天天生鲜项目,记录一下在django中如何使用全文搜索
我们在面对商品搜索时可以通过使用sql语句进行查询,但是这样效率很低,推荐使用全文搜索框架进行检索。

haystack及whoosh介绍

  • haystack 是django的开源搜索框架,该框架支持Solr、Elasticsearch、Whoosh、Xapian搜索引擎,不用直接更改代码,直接切换引擎,减少代码量
  • Whoosh是一个纯python实现的全文搜索引擎,没有二进制文件,比较小巧,配置比较简单,性能略低,但是稳定。

安装和配置

1、 安装python包

  • pip install django-haystack
  • pip install whoosh

2、在settings.py文件中注册应用 haystack,在INSTALLED_APPS中插入haystack

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tinymce',  # 富文本编辑器
    'haystack',  # 全文检索框架
    'apps.user',
    'apps.cart',
    'apps.goods',
    'apps.order',
]

添加全文检索框架配置

# 全文检索框架的配置
HAYSTACK_CONNECTIONS = {
    'default': {
        # 使用whoosh引擎
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        #'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',  # 更换分词方式为结巴分词
        # 索引文件路径
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}

# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'


索引文件的生成

1、在 goods(你需要建立索引的应用) 应用的目录下信新建一个 search_indexes.py(文件名固定)文件,在其中定义一个商品的索引类

# 定义索引类
from haystack import indexes
# 导入你的模型类
from apps.goods.models import GoodsSKU


# 指定对于某个类的某些数据建立索引
# 索引类名格式:模型类名+index

class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
    # 索引字段 use_template=True 指定根据表中的哪些字段建立索引文件,把说明放在一个文件中
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        # 返回你的模型类
        return GoodsSKU

    # 建立索引的数据
    def index_queryset(self, using=None):
        return self.get_model().objects.all()

2、在 templates 下面新建目录 search/indexes/goods,其中searchindexes文件名固定,goods为创建索引的应用名

3、在此目录下新建一个文件goodssku_text.txt文件(其中goodssku为需要创建索引的模型类名的小写),并编辑需要建立索引的字段

# 指定根据表中的哪些字段建立索引数据
{{ object.name }} # 根据商品的名称建立索引
{{ object.desc }} # 根据商品的简介建立索引
{{ object.goods.detail }} # 根据商品的详情建立索引

4、使用命令生成索引文件

python manage.py rebuild_index

会在项目根目录下生成一个whoosh_index的文件夹,文件名是上面在settings.py中配置的

使用全文索引

1、配置url
在项目url下,添加全文索引的url

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^tinymce/', include('tinymce.urls')),  # 富文本编辑器
    url(r'^search/', include('haystack.urls')),  # 全文检索框架
    url(r'^user/', include('apps.user.urls', namespace='user')),  # 用户模块
    url(r'^', include('apps.goods.urls', namespace='goods')),  # 商品模块
    url(r'^cart/', include('apps.cart.urls', namespace='cart')),  # 购物车模块
    url(r'^order/', include('apps.order.urls', namespace='order'))  # 订单模块

]

2、模板下表单搜索时设置表单内容如下:

 <div class="search_con fl">
            <form action="/search" method="get">
                <input type="text" class="input_text fl" name="q" placeholder="搜索商品">
                <input type="submit" class="input_btn fr" name="" value="搜索">
            </form>
        </div>

进行搜索提交时,会通过haystack 搜索数据

3、全文索引结果处理
搜索出结果后,haystack 会把搜索出的结果传递给 templates/search/search.html,文件名和文件夹名固定。

传递的上下文包括:

query:搜索关键字
page:当前页的page对象 -》 遍历 page 对象,获取到的是 SearchResult 类的实例,对象的属性 object 才是模型类的对象
paginator:分页 paginator对象

通过 HAYSTACK_SEARCH_PLER_PAGE可以控制每页显示数量,在settings.py中添加

# 显示指定搜索结果每页显示的条数
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5
 {% for item in page %}
                <li>
                    <a href="{% url 'goods:detail' item.object.id %}"><img src="{{ item.object.image.url }}"></a>
                    <h4><a href="{% url 'goods:detail' item.object.id %}">{{ item.object.name }}</a></h4>
                    <div class="operate">
                        <span class="prize">{{ item.object.price }}</span>
                        <span class="unit">{{ item.object.price }}/{{ item.object.unite }}</span>
                        <a href="#" class="add_goods" title="加入购物车"></a>
                    </div>
                </li>
            {% endfor %}

改变分词方式

全文搜索框架自带的分词方式对部分中文支持不是很好,我们需要替换为结巴分词

1、安装jeiba分词模块

pip install jieba

2、在虚拟环境中找到hytrack的目录下的backends目录

3、在上面backends的目录中新建 ChineseAnalyzer.py文件。

import jieba
from whoosh.analysis import Tokenizer, Token


class ChineseTokenizer(Tokenizer):
    def __call__(self, value, positions=False, chars=False, keeporiginal=False, removestops=True, start_pos=0,
                 start_char=0, mode='', **kwargs):
        t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs)
        seglist = jieba.cut(value, cut_all=True)
        for w in seglist:
            t.original = t.text = w
            t.boost = 1.0
            if positions:
                t.pos = start_pos + value.find(w)
            if chars:
                t.startchar = start_char + value.find(w)
                t.endchar = start_char + value.find(w) + len(w)
            yield t


def ChineseAnalyzer():
    return ChineseTokenizer()

4、复制 whoosh_backend.py文件,改名为whoosh_cn_backend.py

5、打开复制的新文件,引入上面定义的中文解析类,采用jeiba分词,

from .ChineseAnalyzer import ChineseAnalyzer

6、更改词语分析类

查找:
analyzer = StemmingAnalyzer()
改为:
analyzer = ChineseAnalyzer()


7、在 settings.py 文件中配置,将之前定义的whoosh_backend改为whoosh_cn_backend

# 全文检索框架的配置
HAYSTACK_CONNECTIONS = {
    'default': {
        # 使用whoosh引擎
        # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',  # 更换分词方式为结巴分词
        # 索引文件路径
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}

8、重新创建索引


python manage.py rebuild_index
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值