Django利用elasticsearch(搜索引擎)實現搜索功能
1、在Django配置搜索結果頁的路由映射
'''pachong URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/Examples:Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r’^/pre>, views.home, name=’home’)Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r’^/pre>, Home.as_view(), name=’home’)Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r’^blog/’, include(’blog.urls’))'''from django.conf.urls import urlfrom django.contrib import adminfrom app1 import viewsurlpatterns = [ url(r’^admin/’, admin.site.urls), url(r’^/pre>, views.indexluoji), url(r’^index/’, views.indexluoji), url(r’^suggest//pre>, views.suggestluoji,name='suggest'), # 搜索字段補全請求 url(r’^search//pre>, views.searchluoji,name='search'), # 搜索]
2、編寫邏輯處理函數
在邏輯處理函數里實現搜索數據
(1)獲取到用戶的搜索詞
(2)利用原生的elasticsearch(搜索引擎)接口,實現搜索,注明:elasticsearch-dsl就是在原生的elasticsearch上做了封裝
Elasticsearch()方法,連接原生的elasticsearch服務器
search()方法,原生elasticsearch查詢方法,支持原生的elasticsearch查詢語句,返回的原生語句結果也就是字典形式的數據
在查詢語句里進行關鍵詞高亮處理
將查詢到的結果,循環獲取到后返回到html頁面
from django.shortcuts import render# Create your views here.from django.shortcuts import render,HttpResponsefrom django.views.generic.base import Viewfrom app1.models import lagouType # 導入操作elasticsearch(搜索引擎)類import jsonfrom elasticsearch import Elasticsearch # 導入原生的elasticsearch(搜索引擎)接口client = Elasticsearch(hosts=['127.0.0.1']) # 連接原生的elasticsearchdef indexluoji(request): print(request.method) # 獲取用戶請求的路徑 return render(request, ’index.html’)def suggestluoji(request): # 搜索自動補全邏輯處理 key_words = request.GET.get(’s’, ’’) # 獲取到請求詞 re_datas = [] if key_words: s = lagouType.search() # 實例化elasticsearch(搜索引擎)類的search查詢 s = s.suggest(’my_suggest’, key_words, completion={ 'field': 'suggest', 'fuzzy': { 'fuzziness': 1 }, 'size': 5 }) suggestions = s.execute_suggest() for match in suggestions.my_suggest[0].options: source = match._source re_datas.append(source['title']) return HttpResponse(json.dumps(re_datas), content_type='application/json')def searchluoji(request): # 搜索邏輯處理 key_words = request.GET.get(’q’, ’’) # 獲取到請求詞 response = client.search( # 原生的elasticsearch接口的search()方法,就是搜索,可以支持原生elasticsearch語句查詢 index='lagou', # 設置索引名稱 doc_type='biao', # 設置表名稱 body={ # 書寫elasticsearch語句 'query': { 'multi_match': {# multi_match查詢 'query': key_words, # 查詢關鍵詞 'fields': ['title', 'description'] # 查詢字段 } }, 'from': 0, # 從第幾條開始獲取 'size': 10, # 獲取多少條數據 'highlight': { # 查詢關鍵詞高亮處理 'pre_tags': [’<span class='keyWord'>’], # 高亮開始標簽 'post_tags': [’</span>’], # 高亮結束標簽 'fields': { # 高亮設置 'title': {},# 高亮字段 'description': {} # 高亮字段 } } } ) total_nums = response['hits']['total'] # 獲取查詢結果的總條數 hit_list = [] # 設置一個列表來儲存搜索到的信息,返回給html頁面 for hit in response['hits']['hits']: # 循環查詢到的結果 hit_dict = {} # 設置一個字典來儲存循環結果 if 'title' in hit['highlight']: # 判斷title字段,如果高亮字段有類容 hit_dict['title'] = ''.join(hit['highlight']['title']) # 獲取高亮里的title else: hit_dict['title'] = hit['_source']['title'] # 否則獲取不是高亮里的title if 'description' in hit['highlight']: # 判斷description字段,如果高亮字段有類容 hit_dict['description'] = ''.join(hit['highlight']['description'])[:500] # 獲取高亮里的description else: hit_dict['description'] = hit['_source']['description'] # 否則獲取不是高亮里的description hit_dict['url'] = hit['_source']['url'] # 獲取返回url hit_list.append(hit_dict) # 將獲取到內容的字典,添加到列表 return render(request, ’result.html’, {'all_hits': hit_list, 'key_words': key_words}) #顯示頁面和將列表和搜索詞返回到html
3、html頁面接收搜索結果
注意:因為Django實現了防止惡意代碼寫入,凡是通過變量傳輸到html頁面的html類型代碼,將會被自動轉換成字符串方式顯示,索引我們需要在接收變量的字段用:{% autoescape off %} {{ 接收變量 }} {% endautoescape %},來顯示html代碼,
搜索后因為進行了一次跳轉,所以搜索框里的搜索詞將不存在,我們需要在傳遞搜索結果到頁面的時候,將搜索詞也傳遞進來填充到搜索框
<!DOCTYPE html ><html xmlns='http://www.w3.org/1999/xhtml'>{#引入靜態文件路徑#}{% load staticfiles %}<head><meta http-equiv='X-UA-Compatible' content='IE=emulateIE7' /><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><title>python-lcv-search搜索引擎</title><link href='http://www.cgvv.com.cn/bcjs/{% static ’css/style.css’%}' rel='external nofollow' rel='stylesheet' type='text/css' /><link href='http://www.cgvv.com.cn/bcjs/{% static ’css/result.css’%}' rel='external nofollow' rel='stylesheet' type='text/css' /></head><body><div id='container'> <div class='ue-clear'> <a href='http://www.cgvv.com.cn/' rel='external nofollow' ><div class='logo'></div></a> <div class='inputArea'> <input type='text' value='{{ key_words }}'/> <input type='button' onclick='add_search()'/> </div> </div> <div class='nav'> <ul class='searchList'> <li data-type='article'>文章</li> <li data-type='question'>問答</li> <li data-type='job'>職位</li> </ul> </div> <div class='ue-clear'> <div id='main'> <div class='sideBar'> <div class='subfield'>網站</div> <ul class='subfieldContext'> <li> <span class='name'>伯樂在線</span> <span class='unit'>(None)</span> </li> <li> <span class='name'>知乎</span> <span class='unit'>(9862)</span> </li> <li> <span class='name'>拉勾網</span> <span class='unit'>(9862)</span> </li> <li class='more'> <a href='javascript:;' rel='external nofollow' rel='external nofollow' > <span class='text'>更多</span> <i class='moreIcon'></i> </a> </li> </ul> <div class='sideBarShowHide'> <a href='javascript:;' rel='external nofollow' rel='external nofollow' class='icon'></a> </div> </div> <div class='resultArea'> <p class='resultTotal'> <span class='info'>找到約 <span class='totalResult'>45</span> 條結果(用時<span class='time'>0.643128</span>秒),共約<span class='totalPage'>5</span>頁</span> </p> <div class='resultList'> {% for hit in all_hits %} <div class='resultItem'> <div class='itemHead'><a href='http://www.cgvv.com.cn/bcjs/{% autoescape off %} {{ hit.url }} {% endautoescape %}' rel='external nofollow' target='_blank' class='title'>{% autoescape off %} {{ hit.title }} {% endautoescape %}</a><span class='divsion'>-</span><span class='fileType'> <span class='label'>來源:</span> <span class='value'>網絡</span></span><span class='dependValue'> <span class='label'>得分:</span> <span class='value'>3.401155</span></span> </div> <div class='itemBody'>{% autoescape off %} {{ hit.description }} {% endautoescape %} </div> </div> {% endfor %} </div> <!-- 分頁 --> <div class='pagination ue-clear'></div> <!-- 相關搜索 --> </div> <div class='historyArea'> <div class='hotSearch'> <h6>熱門搜索</h6> <ul class='historyList'> <li><a href='http://www.cgvv.com.cn/search?q=linux' rel='external nofollow' >linux</a></li> </ul> </div> <div class='mySearch'> <h6>我的搜索</h6> <ul class='historyList'> </ul> </div> </div> </div><!-- End of main --> </div><!--End of bd--></div><div id='foot'>Copyright ©projectsedu.com 版權所有 E-mail:[email protected]</div></body><script type='text/javascript' src='http://www.cgvv.com.cn/bcjs/{% static ’js/jquery.js’%}'></script><script type='text/javascript' src='http://www.cgvv.com.cn/bcjs/{% static ’js/global.js’%}'></script><script type='text/javascript' src='http://www.cgvv.com.cn/bcjs/{% static ’js/pagination.js’%}'></script><script type='text/javascript'> var search_url = '/search/' $(’.searchList’).on(’click’, ’.searchItem’, function(){ $(’.searchList .searchItem’).removeClass(’current’); $(this).addClass(’current’); }); $.each($(’.subfieldContext’), function(i, item){ $(this).find(’li:gt(2)’).hide().end().find(’li:last’).show(); }); function removeByValue(arr, val) { for(var i=0; i<arr.length; i++) { if(arr[i] == val) { arr.splice(i, 1); break; } } } $(’.subfieldContext .more’).click(function(e){ var $more = $(this).parent(’.subfieldContext’).find(’.more’); if($more.hasClass(’show’)){ if($(this).hasClass(’define’)){ $(this).parent(’.subfieldContext’).find(’.more’).removeClass(’show’).find(’.text’).text(’自定義’); }else{ $(this).parent(’.subfieldContext’).find(’.more’).removeClass(’show’).find(’.text’).text(’更多’); } $(this).parent(’.subfieldContext’).find(’li:gt(2)’).hide().end().find(’li:last’).show(); }else{ $(this).parent(’.subfieldContext’).find(’.more’).addClass(’show’).find(’.text’).text(’收起’); $(this).parent(’.subfieldContext’).find(’li:gt(2)’).show(); } }); $(’.sideBarShowHide a’).click(function(e) { if($(’#main’).hasClass(’sideBarHide’)){ $(’#main’).removeClass(’sideBarHide’); $(’#container’).removeClass(’sideBarHide’); }else{ $(’#main’).addClass(’sideBarHide’); $(’#container’).addClass(’sideBarHide’); } }); var key_words = 'java' //分頁 $('.pagination').pagination(45, { current_page :0, //當前頁碼 items_per_page :10, display_msg :true, callback :pageselectCallback }); function pageselectCallback(page_id, jq) { window.location.href=search_url+’?q=’+key_words+’&p=’+page_id } setHeight(); $(window).resize(function(){ setHeight(); }); function setHeight(){ if($(’#container’).outerHeight() < $(window).height()){ $(’#container’).height($(window).height()-33); } }</script><script type='text/javascript'> $(’.searchList’).on(’click’, ’.searchItem’, function(){ $(’.searchList .searchItem’).removeClass(’current’); $(this).addClass(’current’); }); // 聯想下拉顯示隱藏 $(’.searchInput’).on(’focus’, function(){ $(’.dataList’).show() }); // 聯想下拉點擊 $(’.dataList’).on(’click’, ’li’, function(){ var text = $(this).text(); $(’.searchInput’).val(text); $(’.dataList’).hide() }); hideElement($(’.dataList’), $(’.searchInput’));</script><script> var searchArr; //定義一個search的,判斷瀏覽器有無數據存儲(搜索歷史) if(localStorage.search){ //如果有,轉換成 數組的形式存放到searchArr的數組里(localStorage以字符串的形式存儲,所以要把它轉換成數組的形式) searchArr= localStorage.search.split(',') }else{ //如果沒有,則定義searchArr為一個空的數組 searchArr = []; } //把存儲的數據顯示出來作為搜索歷史 MapSearchArr(); function add_search(){ var val = $('.searchInput').val(); if (val.length>=2){ //點擊搜索按鈕時,去重 KillRepeat(val); //去重后把數組存儲到瀏覽器localStorage localStorage.search = searchArr; //然后再把搜索內容顯示出來 MapSearchArr(); } window.location.href=search_url+’?q=’+val+'&s_type='+$('.searchItem.current').attr(’data-type’) } function MapSearchArr(){ var tmpHtml = ''; var arrLen = 0 if (searchArr.length > 6){ arrLen = 6 }else { arrLen = searchArr.length } for (var i=0;i<arrLen;i++){ tmpHtml += ’<li><a href='http://www.cgvv.com.cn/search?q=’+searchArr[i]+’' rel='external nofollow' >’+searchArr[i]+’</a></li>’ } $('.mySearch .historyList').append(tmpHtml); } //去重 function KillRepeat(val){ var kill = 0; for (var i=0;i<searchArr.length;i++){ if(val===searchArr[i]){ kill ++; } } if(kill<1){ searchArr.unshift(val); }else { removeByValue(searchArr, val) searchArr.unshift(val) } }</script></html>
最終效果
到此這篇關于Django利用elasticsearch(搜索引擎)實現搜索功能的文章就介紹到這了,更多相關Django elasticsearch 搜索 內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章: