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行。
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 搜尋引擎。
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")