Django集成搜索引擎Elasticserach的方法示例
1.背景
當用戶在搜索框輸入關(guān)鍵字后,我們要為用戶提供相關(guān)的搜索結(jié)果??梢赃x擇使用模糊查詢 like 關(guān)鍵字實現(xiàn),但是 like 關(guān)鍵字的效率極低。查詢需要在多個字段中進行,使用 like 關(guān)鍵字也不方便,另外分詞的效果也不理想。
全文檢索方案
- 全文檢索即在指定的任意字段中進行檢索查詢。
- 全文檢索方案需要配合搜索引擎來實現(xiàn)。
搜索引擎原理
- 搜索引擎 進行全文檢索時,會對數(shù)據(jù)庫中的數(shù)據(jù)進行一遍預(yù)處理,單獨建立起一份 索引結(jié)構(gòu)數(shù)據(jù) 。
- 索引結(jié)構(gòu)數(shù)據(jù) 類似字典的索引檢索頁 ,里面包含了關(guān)鍵詞與詞條的對應(yīng)關(guān)系,并記錄詞條的位置。
- 搜索引擎進行全文檢索時,將 關(guān)鍵字在索引數(shù)據(jù)中進行快速對比查找,進而找到數(shù)據(jù)的真實存儲位置 。
2.Elasticsearch介紹
實現(xiàn)全文檢索的搜索引擎,首選的是 Elasticsearch 。
- Elasticsearch 是用 Java 實現(xiàn)的,開源的搜索引擎。
- 它可以快速地儲存、搜索和分析海量數(shù)據(jù)。維基百科、Stack Overflow、Github等都采用它。
- Elasticsearch 的底層是開源庫Lucene。但是,沒法直接使用 Lucene,必須自己寫代碼去調(diào)用它的接口。
分詞說明
搜索引擎在對數(shù)據(jù)構(gòu)建索引時,需要進行分詞處理。
分詞是指將一句話拆解成 多個單字 或 詞 ,這些字或詞便是這句話的關(guān)鍵詞。
Elasticsearch 不支持對中文進行分詞建立索引,需要配合擴展 elasticsearch-analysis-ik 來實現(xiàn)中文分詞處理。
3.集成Elasticsearch
3.1. Haystack介紹和安裝配置
- Haystack 是在Django中對接搜索引擎的框架,搭建了用戶和搜索引擎之間的溝通橋梁。
- 我們在Django中可以通過使用 Haystack 來調(diào)用 Elasticsearch 搜索引擎。
- Haystack 可以在不修改代碼的情況下使用不同的搜索后端(比如 Elasticsearch 、 Whoosh 、 Solr 等等)。
Haystack安裝
$ pip install django-haystack $ pip install elasticsearch==2.4.1
Haystack注冊應(yīng)用和路由
在 django 的配置文件中注冊。
INSTALLED_APPS = [ 'haystack', # 全文檢索注冊]
在總路由中新建 haystack 的路由。
urlpatterns = [url(r'^search/', include('haystack.urls')),]
Haystack配置
在配置文件中配置Haystack為搜索引擎后端
# Haystack
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://192.168.103.158:9200/', # Elasticsearch服務(wù)器ip地址,端口號固定為9200
'INDEX_NAME': 'serach_mall', # Elasticsearch建立的索引庫的名稱
},
}
# 當添加、修改、刪除數(shù)據(jù)時,自動生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# 搜索的每頁大小
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 3
HAYSTACK_SIGNAL_PROCESSOR 配置項保證了在Django運行起來后,有新的數(shù)據(jù)產(chǎn)生時,Haystack仍然可以讓Elasticsearch實時生成新數(shù)據(jù)的索引。
3.2 Haystack建立數(shù)據(jù)索引
1.創(chuàng)建索引類
通過創(chuàng)建索引類,來指明讓搜索引擎對哪些字段建立索引,也就是可以通過哪些字段的關(guān)鍵字來檢索數(shù)據(jù)。
本項目中對模型類SKU信息進行全文檢索,所以在 該模型類的應(yīng)用(goods)中 新建 search_indexes.py 文件,用于存放索引類。索引類必須繼承 haystack.indexes.SearchIndex 與 haystack.indexes.Indexable .
from haystack import indexes from .models import SKU class SKUIndex(indexes.SearchIndex, indexes.Indexable): """SKU索引數(shù)據(jù)模型類""" text = indexes.CharField(document=True, use_template=True) def get_model(self): """返回建立索引的模型類""" return SKU def index_queryset(self, using=None): """返回要建立索引的數(shù)據(jù)查詢集""" return self.get_model().objects.filter(is_launched=True)
索引類 SKUIndex 說明:
- 在 SKUIndex 建立的字段,都可以借助 Haystack 由 Elasticsearch 搜索引擎查詢。
- 其中 text 字段我們聲明為 document=True ,表名該字段是主要進行關(guān)鍵字查詢的字段。
- text 字段的索引值可以由多個數(shù)據(jù)庫模型類字段組成,具體由哪些模型類字段組成,我們用 use_template=True 表示后續(xù)通過模板來指明。
2.創(chuàng)建text字段索引值模板文件
在項目 templates 目錄中創(chuàng)建 text字段 使用的模板文件
具體在 templates/search/indexes/goods/sku_text.txt 文件中定義,其中 goods 為應(yīng)用名, sku_text.txt 中的 sku 為模型類小寫。
{{ object.id }}
{{ object.name }}
{{ object.caption }}
模板文件說明:當將關(guān)鍵詞通過text參數(shù)名傳遞時
此模板指明SKU的 id 、 name 、 caption 作為 text 字段的索引值來進行關(guān)鍵字索引查詢。
3.手動生成初始索引
$ python manage.py rebuild_index
第一次需要生成索引需要執(zhí)行上述命令,后續(xù)會自動生成索引。
3.3 全文檢索測試
準備測試表單
- 請求方法: GET
- 請求地址: /search/
- 請求參數(shù): q
<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> ... ... </div>
然后在 templates/search/ 目錄下新建 search.html 接收和渲染全文檢索的結(jié)果 .
3.4 渲染搜索結(jié)果
Haystack返回的數(shù)據(jù)包括:
- query :搜索關(guān)鍵字
- paginator :分頁paginator對象
- page :當前頁的page對象(遍歷 page 中的對象,可以得到 result 對象)
- result.objects : 當前遍歷出來的SKU對象。
<div class="main_wrap clearfix">
<div class=" clearfix">
<ul class="goods_type_list clearfix">
{% for result in page %}
<li>
{# object取得才是sku對象 #}
<a href="/detail/{{ result.object.id }}/" rel="external nofollow" rel="external nofollow" ><img src="{{ result.object.default_image.url }}"></a>
<h4><a href="/detail/{{ result.object.id }}/" rel="external nofollow" rel="external nofollow" >{{ 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>
這里Elasticsearch替我們把django中的視圖函數(shù)寫了。
搜索頁分頁器
<div class="main_wrap clearfix">
<div class=" clearfix">
......
<div class="pagenation">
<div id="pagination" class="page"></div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#pagination').pagination({
currentPage: {{ page.number }},
totalPage: {{ paginator.num_pages }},
callback:function (current) {
window.location.href = '/search/?q={{ query }}&page=' + current;
}
})
});
</script>
這里使用的 jquery.pagination.js 接收要渲染的數(shù)據(jù),當然也可以使用其他框架的分頁器或自定義的來接收。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
pandas.DataFrame 根據(jù)條件新建列并賦值的方法
下面小編就為大家分享一篇pandas.DataFrame 根據(jù)條件新建列并賦值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
python中sklearn庫predict及python sklearn linearmodel(
Scikit-learn(sklearn)是機器學(xué)習中常用的第三方模塊,對常用的機器學(xué)習方法進行了封裝,包括回歸(Regression)、降維(Dimensionality Reduction)、分類(Classfication)、聚類(Clustering)等方法,今天小編給大家分享python中sklearn庫predict的問題,感興趣的朋友一起看看吧2024-02-02
Python ValueError: invalid literal for int() with base 10 實用
這篇文章主要介紹了Python ValueError: invalid literal for int() with base 10 實用解決方法,本文使用了一個取巧方法解決了這個問題,需要的朋友可以參考下2015-06-06

