Django利用elasticsearch(搜索引擎)實(shí)現(xiàn)搜索功能
1、在Django配置搜索結(jié)果頁的路由映射
"""pachong URL Configuration
The `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 url
from django.contrib import admin
from app1 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^/pre>, views.indexluoji),
url(r'^index/', views.indexluoji),
url(r'^suggest//pre>, views.suggestluoji,name="suggest"), # 搜索字段補(bǔ)全請求
url(r'^search//pre>, views.searchluoji,name="search"), # 搜索
]
2、編寫邏輯處理函數(shù)
在邏輯處理函數(shù)里實(shí)現(xiàn)搜索數(shù)據(jù)
(1)獲取到用戶的搜索詞
(2)利用原生的elasticsearch(搜索引擎)接口,實(shí)現(xiàn)搜索,注明:elasticsearch-dsl就是在原生的elasticsearch上做了封裝
Elasticsearch()方法,連接原生的elasticsearch服務(wù)器
search()方法,原生elasticsearch查詢方法,支持原生的elasticsearch查詢語句,返回的原生語句結(jié)果也就是字典形式的數(shù)據(jù)
在查詢語句里進(jìn)行關(guān)鍵詞高亮處理
將查詢到的結(jié)果,循環(huán)獲取到后返回到html頁面
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render,HttpResponse
from django.views.generic.base import View
from app1.models import lagouType # 導(dǎo)入操作elasticsearch(搜索引擎)類
import json
from elasticsearch import Elasticsearch # 導(dǎo)入原生的elasticsearch(搜索引擎)接口
client = Elasticsearch(hosts=["127.0.0.1"]) # 連接原生的elasticsearch
def indexluoji(request):
print(request.method) # 獲取用戶請求的路徑
return render(request, 'index.html')
def suggestluoji(request): # 搜索自動補(bǔ)全邏輯處理
key_words = request.GET.get('s', '') # 獲取到請求詞
re_datas = []
if key_words:
s = lagouType.search() # 實(shí)例化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", # 設(shè)置索引名稱
doc_type="biao", # 設(shè)置表名稱
body={ # 書寫elasticsearch語句
"query": {
"multi_match": { # multi_match查詢
"query": key_words, # 查詢關(guān)鍵詞
"fields": ["title", "description"] # 查詢字段
}
},
"from": 0, # 從第幾條開始獲取
"size": 10, # 獲取多少條數(shù)據(jù)
"highlight": { # 查詢關(guān)鍵詞高亮處理
"pre_tags": ['<span class="keyWord">'], # 高亮開始標(biāo)簽
"post_tags": ['</span>'], # 高亮結(jié)束標(biāo)簽
"fields": { # 高亮設(shè)置
"title": {}, # 高亮字段
"description": {} # 高亮字段
}
}
}
)
total_nums = response["hits"]["total"] # 獲取查詢結(jié)果的總條數(shù)
hit_list = [] # 設(shè)置一個列表來儲存搜索到的信息,返回給html頁面
for hit in response["hits"]["hits"]: # 循環(huán)查詢到的結(jié)果
hit_dict = {} # 設(shè)置一個字典來儲存循環(huán)結(jié)果
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) # 將獲取到內(nèi)容的字典,添加到列表
return render(request, 'result.html', {"all_hits": hit_list, "key_words": key_words}) #顯示頁面和將列表和搜索詞返回到html
3、html頁面接收搜索結(jié)果
注意:因?yàn)镈jango實(shí)現(xiàn)了防止惡意代碼寫入,凡是通過變量傳輸?shù)絟tml頁面的html類型代碼,將會被自動轉(zhuǎn)換成字符串方式顯示,索引我們需要在接收變量的字段用:{% autoescape off %} {{ 接收變量 }} {% endautoescape %},來顯示html代碼,
搜索后因?yàn)檫M(jìn)行了一次跳轉(zhuǎn),所以搜索框里的搜索詞將不存在,我們需要在傳遞搜索結(jié)果到頁面的時候,將搜索詞也傳遞進(jìn)來填充到搜索框
<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml">
{#引入靜態(tài)文件路徑#}
{% 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="{% static 'css/style.css'%}" rel="external nofollow" rel="stylesheet" type="text/css" />
<link href="{% static 'css/result.css'%}" rel="external nofollow" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container">
<div id="hd" class="ue-clear">
<a href="/" rel="external nofollow" ><div class="logo"></div></a>
<div class="inputArea">
<input type="text" class="searchInput" value="{{ key_words }}"/>
<input type="button" class="searchButton" onclick="add_search()"/>
</div>
</div>
<div class="nav">
<ul class="searchList">
<li class="searchItem current" data-type="article">文章</li>
<li class="searchItem" data-type="question">問答</li>
<li class="searchItem" data-type="job">職位</li>
</ul>
</div>
<div id="bd" class="ue-clear">
<div id="main">
<div class="sideBar">
<div class="subfield">網(wǎng)站</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">拉勾網(wǎng)</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> 條結(jié)果(用時<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="{% 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">網(wǎng)絡(luò)</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>
<!-- 相關(guān)搜索 -->
</div>
<div class="historyArea">
<div class="hotSearch">
<h6>熱門搜索</h6>
<ul class="historyList">
<li><a href="/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 版權(quán)所有 E-mail:admin@projectsedu.com</div>
</body>
<script type="text/javascript" src="{% static 'js/jquery.js'%}"></script>
<script type="text/javascript" src="{% static 'js/global.js'%}"></script>
<script type="text/javascript" src="{% 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, //當(dāng)前頁碼
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');
});
// 聯(lián)想下拉顯示隱藏
$('.searchInput').on('focus', function(){
$('.dataList').show()
});
// 聯(lián)想下拉點(diǎn)擊
$('.dataList').on('click', 'li', function(){
var text = $(this).text();
$('.searchInput').val(text);
$('.dataList').hide()
});
hideElement($('.dataList'), $('.searchInput'));
</script>
<script>
var searchArr;
//定義一個search的,判斷瀏覽器有無數(shù)據(jù)存儲(搜索歷史)
if(localStorage.search){
//如果有,轉(zhuǎn)換成 數(shù)組的形式存放到searchArr的數(shù)組里(localStorage以字符串的形式存儲,所以要把它轉(zhuǎn)換成數(shù)組的形式)
searchArr= localStorage.search.split(",")
}else{
//如果沒有,則定義searchArr為一個空的數(shù)組
searchArr = [];
}
//把存儲的數(shù)據(jù)顯示出來作為搜索歷史
MapSearchArr();
function add_search(){
var val = $(".searchInput").val();
if (val.length>=2){
//點(diǎn)擊搜索按鈕時,去重
KillRepeat(val);
//去重后把數(shù)組存儲到瀏覽器localStorage
localStorage.search = searchArr;
//然后再把搜索內(nèi)容顯示出來
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="/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>
最終效果

到此這篇關(guān)于Django利用elasticsearch(搜索引擎)實(shí)現(xiàn)搜索功能的文章就介紹到這了,更多相關(guān)Django elasticsearch 搜索 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python linecache 處理固定格式文本數(shù)據(jù)的方法
今天小編就為大家分享一篇python linecache 處理固定格式文本數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01
利用Python實(shí)現(xiàn)快速批量轉(zhuǎn)換HEIC文件
HEIC 是蘋果采用的新的默認(rèn)圖片格式,它能在不損失圖片畫質(zhì)的情況下,減少圖片大小。本篇文章將使用 Python 批量實(shí)現(xiàn) HEIC 圖片文件的格式轉(zhuǎn)換,需要的可以參考一下2022-07-07
ubuntu在線服務(wù)器python?Package安裝到離線服務(wù)器的過程
這篇文章主要介紹了ubuntu在線服務(wù)器python?Package安裝到離線服務(wù)器,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
舉例講解Python的Tornado框架實(shí)現(xiàn)數(shù)據(jù)可視化的教程
這篇文章主要介紹了舉例講解Python的Tornado框架實(shí)現(xiàn)數(shù)據(jù)可視化的教程,Tornado是一個異步的高人氣開發(fā)框架,需要的朋友可以參考下2015-05-05
python opencv對圖像進(jìn)行旋轉(zhuǎn)且不裁剪圖片的實(shí)現(xiàn)方法
今天小編就為大家分享一篇python opencv對圖像進(jìn)行旋轉(zhuǎn)且不裁剪圖片的實(shí)現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07

