close

Python Django 學習紀錄(十)  使用whoosh+haystack+jieba進行中文模糊搜索

一.概要

 1.搜索引擎whoosh

搜索引擎會做那些事?

  1. 創建數據索引表
  2. 進行分詞操作

 2.搜索框架haystack

搜索框架與搜尋引擎對接

haystack搭載了用戶與搜索引擎之間的橋樑

將與引擎的接口進行統一的封裝

haystack的概念:

搜索框輸入關鍵字→透過網路方式傳給haystack所對應的接口→查詢後返回值

 

二.配置流程

pip安裝

  • django-haystack
  • whoosh
  • jieba 

1.在<settings.py>的App註冊haystack

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Yourapp',
    'haystack',
]

2.在<settings.py>配置對應的搜索框架

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine', #_cn在沒設置好jieba時可以先拿掉
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'   # 索引自動更新

當添加、修改、刪除數據時,會自動生成最新索引

但要透過django操作才會,若直接修改數據庫就不會更動索引

3.設置url路徑

在專案的<urls.py>添加

from django.urls import include
    path('search/',include('haystack.urls')),

4.在應用中創建文檔search_indexes.py

在應用目錄(Yourapp)創建<search_indexes.py>

在haystack創建索引時會從應用所在的文檔夾中去尋找這個文檔

以 類 的形式進行溝通,要創建對於模型的索引,通常取名為 模型名稱+index

類會繼承haystack的信息,有兩個參數 (創建索引、是否可以創建索引)

後面加上text字段設置模板信息、使用模板傳遞創建字段索引的信息給模型

最後會有兩個方法:指名模型類(從哪張表創建索引)、指名字段(從表的哪個數據創建索引)

以下為範例:

from haystack import indexes
from Yourapp.models import Yourappmodel


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

    def get_model(self):
        return Yourappmodel

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

5.設置取出的資料欄位

在應用目錄下的templates創建search/indexes/Yourapp/yourappmodel_text.text

取出models中資料表的欄位名稱

以下為範例:

{{ object.欄位名稱 }}

6.設置whoosh搜尋引擎、導入jieba中文分詞

在該專案虛擬環境的目錄找到\Lib\site-packages\haystack\backends\whoosh_backend.py

開啟並導入中文分析套件,修改後改名為whoosh_cn_backend.py(若settings的設置原先拿掉_cn須補回)

以下為範例:

#導入,不可放在第一行  
from jieba.analyse import ChineseAnalyzer
#找到
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)
#修改為
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)


7.前端頁面配置

這邊只做個基礎的展示

搜尋框:

<form role="search" method="get" id="searchform" action="{% url 'haystack_search' %}">
  <input type="search" name="q" placeholder="搜索" required>
  <button type="submit"><span class="ion-ios-search-strong"></span></button>
</form>

在search目錄創建search.html:

{% extends 'base.html' %}
{% load highlight %}

{% block content %}
    {% if query %}
        {% for result in page.object_list %}
            <article class="post post-{{ result.object.pk }}">
                <header class="entry-header">
                    <h1 class="entry-title">
                        <p>{% highlight result.object.goodname with query %}</p>
                    </h1>

                    </div>
                </header>

            </article>
        {% empty %}
            <div class="no-post">查無資料!</div>
        {% 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 %}
        請輸入關鍵詞!
    {% endif %}
{% endblock content %}

7.建立索引

在專案虛擬環境命令輸入:

python manage.py rebuild_index

建立好後runserver即可成功搜索

arrow
arrow
    全站熱搜

    ivankao 發表在 痞客邦 留言(0) 人氣()