快速搭建搜索引擎。haystack + whoosh(Django)

部署:

在settings.py文件中注册haystack, 并做如下配置:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',

    # Added.
    'haystack',

    # Then your usual apps...
    'blog',
]
import os
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
    },
}


在应用目录下创建一个search_indexes.py

import datetime
from haystack import indexes
from myapp.models import Note


class NoteIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    author = indexes.CharField(model_attr='user')
    pub_date = indexes.DateTimeField(model_attr='pub_date')

    def get_model(self):
        return Note

    def index_queryset(self, using=None):
        """Used when the entire index for model is updated."""
        return self.get_model().objects.filter(pub_date__lte=datetime.datetime.now())
use_template=True 说明您一会会在一个文件中指定要建立索引的字段,这个一会我们会说。建立索引,是说要搜索哪些字段,没有建立索引的字段不在搜索的范围之内。
需要注意的是,类名是由学问的,它的组成是要建立索引的模型类+Index,比如,我要搜索的模型类是GoodsSKU,那么我的类名就是GoodsSKU,也就是:
class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
    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()
在templates下建目录search/indexes/myapp/GoodsSKU_text.txt, 这里面要指定的,就是刚刚说的要建立索引的字段。
{{ object.name }}# 根据商品的名称建立索引
{{ object.desc }}# 根据商品的简介建立索引
{{ object.goods.detail }} # 根据商品详情信息建立索引
./manage.py rebuild_index      这个命令会生成索引
配置URL:
url(r'^search/', include('haystack.urls')),
基本的部署已经结束了,接下来就是使用了。
一般,我们会在首页建一个form,来调用搜索引擎。


    <form method="get" action=".">
        <table>
            {{ form.as_table }}
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="Search">
                </td>
            </tr>
        </table>

        {% if query %}
            <h3>Results</h3>

            {% for result in page.object_list %}
                <p>
                    <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
                </p>
            {% empty %}
                <p>No results found.</p>
            {% endfor %}

            {% if page.has_previous or page.has_next %}
                <div>
                    {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}
                    |
                    {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
                </div>
            {% endif %}
        {% else %}
            {# Show some example queries to run, maybe query syntax, something else? #}
        {% endif %}
    </form>
上面的是官方示例,这个示例少个输入框。我补充下:
<input type="text" name = 'q' >    大家要注意,name = 'q'是不能更改的,只能这么写。
搜索结果出来后,搜索引擎会把结果返给emplates/search目录下的search.html
具体返回的内容包括:
query    搜索关键词
page     当前页的page对象(引擎默认已经给搜索结果分页了)
paginator    分页对象
这里需要特别指出的是,遍历page后,需要在后面加上.object,这样得到的才是模型类对象。

HAYSTACK_SEARCH_RESULTS_PER_PAGE 可以用来指定每页显示的条目数,写在settings里。

到此为止,搜索引擎就已经可以正常使用了。但是,在使用的过程中,我们可能会对引擎的分词能力不满意。那么,我们可以安装jieba。它的一个优势就是——免费!

pip install jieba

找到虚拟环境py_django下的haystack目录。
/home/python/.virtualenvs/bj17_py3/lib/python3.5/site-packages/haystack/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()

复制whoosh_backend.py文件,改为如下名称。
	whoosh_cn_backend.py

打开复制出来的新文件,引入中文分析类,内部采用jieba分词。
from .ChineseAnalyzer import ChineseAnalyzer
更改词语分析类。
查找
analyzer=StemmingAnalyzer()
改为
analyzer=ChineseAnalyzer()

修改settings.py文件中的配置项。把其中的,whoosh_backend改为whoosh_cn_backend

然后重启搜索引擎,大功告成!python manage.py rebuild_index

 




    <form method="get" action=".">
        <table>
            {{ form.as_table }}
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="Search">
                </td>
            </tr>
        </table>

        {% if query %}
            <h3>Results</h3>

            {% for result in page.object_list %}
                <p>
                    <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
                </p>
            {% empty %}
                <p>No results found.</p>
            {% endfor %}

            {% if page.has_previous or page.has_next %}
                <div>
                    {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}
                    |
                    {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
                </div>
            {% endif %}
        {% else %}
            {# Show some example queries to run, maybe query syntax, something else? #}
        {% endif %}
    </form>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值