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

来源:互联网 发布:网络电视浏览器下载 编辑:程序博客网 时间:2024/06/10 17:37

部署:

在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 datetimefrom haystack import indexesfrom myapp.models import Noteclass 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 jiebafrom whoosh.analysis import Tokenizer, Tokenclass 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 tdef 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>
原创粉丝点击