文章目錄
- 一、全文檢索和搜索引擎原理
- 1.商品搜索需求
- 2.商品搜索實作
- 3.全文檢索方案
- 4.搜索引擎原理
- 二、Elasticsearch介紹
- 三、Docker安裝Elasticsearch
- 四、haystack擴展建立索引
- 1. Haystack介紹和安裝配置
- 1.1 Haystack介紹
- 1.2 Haystack安裝
- 1.3 Haystack注冊應用和路由
- 1.4測驗
- 五、自定義頁面訪問
- 1.創建索引類
- 2.創建序列化器
- 3.最后創建建立索引的資料
- 4.創建視圖
- 5.創建索引的序列器
- 6.在我們應用的路由中進行注冊
一、全文檢索和搜索引擎原理
1.商品搜索需求
當用戶在搜索框輸入商品關鍵字后,我們要為用戶提供相奐的商品搜索結果,
2.商品搜索實作
可以選擇使用模糊查詢like突鍵字實作,
但是like關鍵字的效率極低,
查詢需要在多個欄位中進行,使用like關鍵字也不方便,
3.全文檢索方案
我們引入全文檢索的方案來實作商品搜索,
全文檢索即在指定的任意欄位中進行檢索查詢,
全文檢索方案需要配合搜索引擎來實作,
4.搜索引擎原理
搜索引擎進行全文檢索時,會對資料庫中的資料進行一遍預處理,單獨建立起一份索引結構資料,
索引結構資料類似新華字典的索引檢索頁,里面包含了關鍵詞與詞條的對應失系,并記錄詞條的位置,
搜索引擎進行全文檢索時,將關鍵字在索引資料中進行快速對比查找,進而找到資料的真實存盤位置,
二、Elasticsearch介紹
實作全文檢索的搜索引擎,首選的是Elasticsearch,
- Elasticsearch是用Java實作的,開源的搜索引擎,
- 它可以快速地儲存、搜索和分析海量資料,維基百科、Stack Overflow Github等都采用它,
- Elasticsearch的底層是開源庫Lucene,但是,沒法直接使用Lucene,必須自己寫代碼去呼叫它的介面,
分詞說明
- 搜索引擎在對資料構建索引時,需要進行分詞處理,
- 分詞是指將一句話拆解成多個單字或詞,這些字或詞便是這句話的奐鍵詞, 比如:我是中國人
- 分詞后:我、是、中、國、人、中國等等都可以是這句話的關鍵字,
- Elasticsearch不支持對中文進行分詞建立索引,需要配合擴展elasticsearch-analysis-ik來實作中文
三、Docker安裝Elasticsearch
獲取鏡像,可以通過網路pull
docker image pull delron/elasticsearch-ik:2.4.6-1.0
或者用自己拉取好的鏡像檔案:
docker load -i elasticsearch-ik-2.4.6_docker.tar
修改elasticsearch的組態檔 elasticsearc-2.4.6/config/elasticsearch.yml第54行,更改ip地址為本機ip地址
network.host: 127.0.0.1
創建docker容器運行
docker run -dti --network=host --name=elasticsearch -v /home/python/elasticsearch-2.4.6/config:/usr/share/elasticsearch/config Desktop/elasticsearch-ik:2.4.6-1.0

出現如下表示服務已經成功運行了

四、haystack擴展建立索引
1. Haystack介紹和安裝配置
1.1 Haystack介紹
- Haystack是在Django中對接搜索引擎的框架,搭建了用戶和搜索引擎之間的溝通橋梁,
- 我們在Django中可以通過使用Haystack來呼叫Elasticsearch搜索引擎,
- Haystack可以在不修改代碼的情況下使用不同的搜索后端(比如Elasticsearch、whoosh、Solr等等),
1.2 Haystack安裝
pip install django-haystack
pip install elasticsearch==2.4.6
1.3 Haystack注冊應用和路由
應用配置中加上如下應用
INSTALLED_APPS = [
"haystack',#全文檢索
]
# Haystack
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/', # 此處為elasticsearch運行的服務器ip地址,埠號固定為9200
'INDEX_NAME': 'xxshopping', # 指定elasticsearch建立的索引庫的名稱
},
}
# 當添加、修改、洗掉資料時,自動生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
創建search_indexes.py在對應的商品目錄下
from haystack import indexes
from apps.goods.models import SKU
class SKUIndex(indexes.SearchIndex,indexes.Indexable):
# 每個都SearchIndex需要有一個(也是唯一一個)欄位 document=True,
# 這向Haystack和搜索引擎指示哪個欄位是用于在其中搜索的主要欄位,
#允許我們使用資料模板(而不是容易出錯的串聯)來構建搜索引擎將索引的檔案
# 'name,caption,id'
#慣例是命名此欄位text
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
# 回傳對哪個模型進行檢索
return SKU
def index_queryset(self, using=None):
#對哪些資料進行檢索
return self.get_model().objects.filter(is_launched=True)
# return self.get_model().objects.all()
# return SKU.objects.all()
# pass
# class SPUIndex(indexes.SearchIndex, indexes.Indexable):
# # 每個都SearchIndex需要有一個(也是唯一一個)欄位 document=True,
# # 這向Haystack和搜索引擎指示哪個欄位是用于在其中搜索的主要欄位,
#
# # 慣例是命名此欄位text
# text = indexes.CharField(document=True, use_template=True)
在模板里新建sku_text.txt檔案

# 在這里我們指定 對模型的哪些欄位進行檢索
# object 可以理解為 SKU的實體物件
{{ object.name }}
{{ object.caption }}
{{ object.id }}
在全域路由檔案下添加
re_path('^search/', include('haystack.urls'))
添加視圖search.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>小徐商城-商品搜索</title>
<link rel="stylesheet" type="text/css" href="{{ static('css/jquery.pagination.css') }}">
<link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}">
<link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}">
<script type="text/javascript" src="{{ static('js/jquery-1.12.4.min.js') }}"></script>
<script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script>
<script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
</head>
<body>
<div id="app">
<div class="header_con">
<div class="header" v-cloak>
<div class="welcome fl">歡迎來到小徐商城!</div>
<div class="fr">
<div v-if="username" class="login_btn fl">
歡迎您:<em>[[ username ]]</em>
<span>|</span>
<a href="#">退出</a>
</div>
<div v-else class="login_btn fl">
<a href="#">登錄</a>
<span>|</span>
<a href="#">注冊</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="#">用戶中心</a>
<span>|</span>
<a href="#">我的購物車</a>
<span>|</span>
<a href="#">我的訂單</a>
</div>
</div>
</div>
</div>
<div class="search_bar clearfix">
<a href="{{ url('contents:index') }}" class="logo fl"><img src="{{ static('images/logo.png') }}"></a>
<div class="search_wrap fl">
<form method="get" action="/search/" class="search_con">
<input type="text" class="input_text fl" name="q" placeholder="搜索商品">
<input type="submit" class="input_btn fr" name="" value="搜索">
</form>
<ul class="search_suggest fl">
<li><a href="#">索尼微單</a></li>
<li><a href="#">優惠15元</a></li>
<li><a href="#">美妝個護</a></li>
<li><a href="#">買2免1</a></li>
</ul>
</div>
</div>
<div class="main_wrap clearfix">
<div class=" clearfix">
<ul class="goods_type_list clearfix">
{% for result in page %}
<li>
{# object取得才是sku物件 #}
<a href="#"><img src="{{ result.object.default_image.url }}"></a>
<h4><a href="#">{{ result.object.name }}</a></h4>
<div class="operate">
<span class="price">¥{{ result.object.price }}</span>
<span>{{ result.object.comments }}評價</span>
</div>
</li>
{% else %}
<p>沒有找到您要查詢的商品,</p>
{% endfor %}
</ul>
<div class="pagenation">
<div id="pagination" class="page"></div>
</div>
</div>
</div>
<div class="footer">
<div class="foot_link">
<a href="#">關于我們</a>
<span>|</span>
<a href="#">聯系我們</a>
<span>|</span>
<a href="#">招聘人才</a>
<span>|</span>
<a href="#">友情鏈接</a>
</div>
<p>CopyRight ? 2016 小徐 All Rights Reserved</p>
<p>電話:010-****888 京ICP備*******8號</p>
</div>
</div>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/search.js') }}"></script>
<script type="text/javascript" src="{{ static('js/jquery.pagination.min.js') }}"></script>
<script type="text/javascript">
$(function () {
$('#pagination').pagination({
currentPage: {{ page.number }},
totalPage: {{ paginator.num_pages }},
callback:function (current) {
window.location.href = '/search/?q=iphone&page=1';
window.location.href = '/search/?q={{ query }}&page=' + current;
}
})
});
</script>
</body>
</html>
最后創建建立索引的資料:
python manage.py rebuild_index
選 y
此時, 在我們的資料庫中就有了我們索引的資料;
1.4測驗
/search/?q=查詢產生
五、自定義頁面訪問
1.創建索引類

2.創建序列化器

3.最后創建建立索引的資料
python manage.py rebuild_index
選Y
4.創建視圖

5.創建索引的序列器

6.在我們應用的路由中進行注冊

最后就是設定我們前端的search.html 的頁面,及對應的js加載檔案;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/423276.html
標籤:其他
