Django-haystack檢索使用,根據原作者文章該寫了部分說明

搜索

  搜索可以使用最原始的模糊匹配的like方式進行搜索。當然這種搜索方式對於一些小量的數據是非常合適的。但是隨着數據量越來越大。這時候我們就需要使用搜索引擎了。搜索引擎會將所有需要搜索的數據使用算法做一個索引,以後搜索的時候就只需要根據這個索引即可找到相應的數據。搜索引擎做索引的過程會比較慢,甚至佔用空間,但是一旦索引建立完成,那麼以後再搜索的時候就會很快了。

django-haystack插件概述

  這個插件是專門給Django提供搜索功能的。django-haystack提供了一個搜索的接口,底層可以根據自己的需求更換搜索引擎。他其實有點類似於Django中的ORM插件,提供了一個操作數據庫的接口,但是底層具體使用哪個數據庫是可以自己設置的。

  django-haystack支持的搜索引擎有Solr、Elasticsearch、Whoosh、Xapian等。Whoosh是基於純Python的搜索引擎,檢索速度快,集成方便。

安裝

1 pip3 install django-haystack
2 pip3 install whoosh

集成步驟

 1.在項目中安裝django-haystack,在settings.py

 

 1 INSTALLED_APPS = [
 2     'django.contrib.admin',
 3     'django.contrib.auth',
 4     'django.contrib.contenttypes',
 5     'django.contrib.sessions',
 6     'django.contrib.sites',
 7 
 8     # 添加
 9     'haystack',
10 ]

 2.設置搜索引擎,在settings中

1 HAYSTACK_CONNECTIONS = {
2     'default': {
3         # 設置haystack的搜索引擎
4         'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
5         # 設置索引文件的位置
6         'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
7     }
8 } 

如果不想每次數據操作後都要手動的創建索引,可以在settings中配置: 

1 # 增刪改查後自動創建索引
2 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

3.創建索引類 

   在模型所屬的app下創建一個search_indexes.py文件,然後創建索引類。假如要給News app創建索引,代碼如下:

class NewsIndex(indexes.SearchIndex,indexes.Indexable):
    text = indexes.CharField(document=True,use_template=True)

    def get_model(self):
        return News

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

4.添加url映射 

1 urlpatterns = [
2     path('',views.index,name='index'),
3     # 添加search的url映射
4     path('search/',include('haystack.urls')),
5     path('news/', include("apps.news.urls")),
6 ] 

5.添加模板

   在templates文件夾下創建以下結構的目錄:

1 templates
2     search
3         indexes
4             news(app的名字)
5                 news(模型的名字)_text.txt 

   然後在news_text.txt中添加需要被索引的字段

1 # 根據標題和內容文本
2 {{ object.title }}
3 {{ object.content }}

  緊接着templates文件下創建search.html模板文件,haystack會自動在templates文件下尋找這個模板文件渲染,並且會給這個模板傳入page/paginator/query等參數,django內置的分頁與查詢的關鍵字。我們可以通過page.object_list獲取到查詢出來的數據。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<ul class="recommend-list">

    {% for result in page.object_list %}

        {% with result.object as news %}

            <li>

                <div class="thumbnail-group">

                    <a href="#">

                        <img src="{{ news.thumbnail }}" alt="">

                    </a>

                </div>

                <div class="news-group">

                    <p class="title">

                        <a href="#">{{ news.title }}</a>

                    </p>

                    <p class="desc">

                        {{ news.desc }}

                    </p>

                    <p class="more">

                       <span class="category">{{ news.caetgory.name }}</span>

                        <span class="pub-time">{{ news.pub_time }}</span>

                        <span class="author">{{ news.author.username }}</span>

                    </p>

                </div>

            </li>

        {% endwith %}

    {% endfor %}

</ul>

6.建立索引  

1 python manage.py rebuild_index 

 7.使用jieba分詞替換Whoosh默認的分詞

  Whoosh默認是採用正則表達式進行分詞的,這對於英文詞彙適用,但是中文支持的不好,這裏替換爲jieba分詞,jieba分詞庫對中文卻支持的好。

  安裝

1 pip3 install jieba

  

  安裝完成後,複製()你的python所在的安裝目錄)E:\python\Lib\site-packages\haystack\backends\whoosh_backend.py其中的代碼,然後在當前目錄創建一個名叫whoosh_cn_backend.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()

  然後再將之前的代碼中的分析器analyzer=StemmingAnalyzer()替換爲analyzer=ChineseAnalyzer()就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章