1. 程式人生 > 其它 >Django + Docker完成es全文解鎖

Django + Docker完成es全文解鎖

技術標籤:django

使用Docker安裝Elasticsearch

1.獲取Elasticsearch-ik映象
#從倉庫拉取映象
$ sudo docker image pull delron/elasticsearch-ik:2.4.6-1.0
#解壓教學資料中本地映象
$ sudo docker load -i elasticsearch-ik-2.4.6_docker.tar

2.配置Elasticsearch-ik
將教學資料中的elasticsearc-2.4.6目錄拷貝到home目錄下。
修改/home/python/elasticsearc-2.4.6/config/elasticsearch.yml第54行。

更改ip地址為本機真實ip地址。
在這裡插入圖片描述

3.使用Docker執行Elasticsearch-ik
$ sudo docker run -dti --name=elasticsearch --network=host -v /home/python/elasticsearch-2.4.6/config:/usr/share/elasticsearch/config delron/elasticsearch-ik:2.4.6-1.0
在這裡插入圖片描述

Haystack介紹和安裝配置

1.Haystack介紹
Haystack 是在Django中對接搜尋引擎的框架,搭建了使用者和搜尋引擎之間的溝通橋樑。
我們在Django中可以通過使用 Haystack 來呼叫 Elasticsearch 搜尋引擎。

Haystack 可以在不修改程式碼的情況下使用不同的搜尋後端(比如 Elasticsearch、Whoosh、Solr等等)。

2.Haystack安裝

$ pip install django-haystack
$ pip install elasticsearch==2.4.1

3.Haystack註冊應用和路由

# settings.py中配置
INSTALLED_APPS = [
    'haystack', # 全文檢索
]
# 路由
path('search/', include('haystack.urls')),

4.Haystack配置
在配置檔案中配置Haystack為搜尋引擎後端

#Haystack
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
        'URL': 'http://192.168.103.158:9200/', # Elasticsearch伺服器ip地址,埠號固定為9200
        'INDEX_NAME': 'meiduo_mall', # Elasticsearch建立的索引庫的名稱
    },
}

#額外的配置,可加可以不加
#當新增、修改、刪除資料時,自動生成索引
HAYSTACK_SIGNAL_PROCESSOR = ‘haystack.signals.RealtimeSignalProcessor’

重要提示:
HAYSTACK_SIGNAL_PROCESSOR 配置項保證了在Django執行起來後,有新的資料產生時,Haystack仍然可以讓Elasticsearch實時生成新資料的索引

Haystack建立資料索引

1.建立索引類

  • 通過建立索引類,來指明讓搜尋引擎對哪些欄位建立索引,也就是可以通過哪些欄位的關鍵字來檢索資料。
  • 本專案中對SKU資訊進行全文檢索,所以在goods應用中新建search_indexes.py檔案(注意名字必須相同),用於存放索引類。

程式碼:

from haystack import indexes

from .models import  模型名稱


class  模型名稱Index(indexes.SearchIndex, indexes.Indexable):


 """模型名稱索引資料模型類"""

 text = indexes.CharField(document=True, use_template=True)


 def get_model(self):

  """返回建立索引的模型類"""

return 模型名稱


  def index_queryset(self, using=None):

  """返回要建立索引的資料查詢集"""

 return self.get_model().objects.filter(is_launched=True)
  • 索引類SKUIndex說明:
    • 在SKUIndex建立的欄位,都可以藉助Haystack由Elasticsearch搜尋引擎查詢。
    • 其中text欄位我們宣告為document=True,表名該欄位是主要進行關鍵字查詢的欄位。
    • text欄位的索引值可以由多個數據庫模型類欄位組成,具體由哪些模型類欄位組成,我們用use_template=True表示後續通過模板來指明。

2.建立text欄位索引值模板檔案

  • 在templates目錄中建立text欄位使用的模板檔案
  • 具體在templates/search/indexes/goods/sku_text.txt檔案(需要建立的資料夾,注意檔名相同)中定義

{{ object.id }}
{{ object.name }}
{{ object.caption }}

  • 模板檔案說明:當將關鍵詞通過text引數名傳遞時
    • 此模板指明SKU的id、name、caption作為text欄位的索引值來進行關鍵字索引查詢。

3.手動生成初始索引

#先再資料庫中新增資料,再執行生成索引

$ python manage.py rebuild_index

在view檢視中的實現es查詢的檢視

#呼叫時需要用get傳入q=查詢的內容
from django.shortcuts import render
#Create your views here.
import json
from django.conf import settings
from django.core.paginator import InvalidPage, Paginator
from django.http import Http404, HttpResponse, JsonResponse
from haystack.forms import ModelSearchForm
from haystack.query import EmptySearchQuerySet

RESULTS_PER_PAGE = getattr(settings, 'HAYSTACK_SEARCH_RESULTS_PER_PAGE', 20)


def basic_search(request, load_all=True, form_class=ModelSearchForm, searchqueryset=None, extra_context=None,
                 results_per_page=None):
    query = ''
    results = EmptySearchQuerySet()
    if request.GET.get('q'):
        form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all)

        if form.is_valid():
            query = form.cleaned_data['q']
            results = form.search()
    else:
        form = form_class(searchqueryset=searchqueryset, load_all=load_all)

    paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE)
    try:
        page = paginator.page(int(request.GET.get('page', 1)))
    except InvalidPage:
        result = {"code": 404, "msg": 'No file found!', "data": []}
        return HttpResponse(json.dumps(result), content_type="application/json")

    context = {
        'form': form,
        'page': page,
        'paginator': paginator,
        'query': query,
        'suggestion': None,
    }
    if results.query.backend.include_spelling:
        context['suggestion'] = form.get_suggestion()

    if extra_context:
        context.update(extra_context)

    jsondata = []
    print(len(page.object_list))
    for result in page.object_list:
        data = {
            'pk': result.object.pk,
            'title': result.object.title,
            'desc': result.object.desc,
        }
        jsondata.append(data)
    result = {"code": 200, "msg": 'Search successfully!', "data": jsondata}
    return JsonResponse(result, content_type="application/json")