Django and elasticsearch search engine site back-end functions to achieve

First, the smart prompt input box (es provides the interface)
modify the type
you need to set a mapping in the field suggest: { "type": "completion "}
So we want to modify the definition of the type:
add a field type in: suggest, Since the es-dsl source there are some problems, so this definition is being given, to their own definition of a CustomAnalyzer, and then declare an object of a custom, ik_analyzer, then type in the object is assigned to suggest:

...
from elasticsearch_dsl.analysis import CustomAnalyzer as _CustomAnalyzer

class CustomAnalyzer(_CustomAnalyzer):

get_analysis_definition DEF (Self):
# here doing nothing, just to avoid being given the problems
return ()


# Declare a custom objects, passing ik_max_word and does case
ik_analyzer = CustomAnalyzer ( 'ik_max_word', filter = [ 'lowercase'])


DuowanType class (DocType):
...
# define suggest is to complete the auto-complete function.
# Since the es-dsl source there are some problems, so this definition is being given, to define themselves a CustomAnalyzer
suggest = Completion (Analyzer = ik_analyzer)

generating suggest value
generated search suggestions save_to_es which
to generate their own by generating suggest interface structure.
Class is defined in a global function items gen_suggests, info_tuple for transmitting the index and weight information is used to create a set weight, suggest a content storage array for the return. Traversal info_tuple, if the text string is not empty, es's analyze the interface is called to parse the string, and then collated need to return to the structure

def gen_suggests (index, info_tuple): # tuple with a plurality of weight information can be transmitted and may also be sequentially
# character string search suggestions generated array
uesd_words = set () # is used to weight
suggests = [] # for return
for text, in info_tuple weight:
IF text: negative empty string #
# call es analyze the interface to parse the string of
words = es.indices.analyze (index = index, analyzer = 'ik_max_word', params = { 'filter': [ 'lowercase']}, body text =)
anylyzed_words = SET (R & lt [ "token"] for R & lt words in [ "tokens"] IF len (R & lt [ "token"])>. 1) used to filter a single word #
new_words = anylyzed_words - uesd_words # weight to
the else:
new_words = SET ()
IF new_words:
suggests.append ({ 'INPUT': List (new_words), 'weight': weight})
return Suggests

call that function in the save_to_es:

= info_tuple ((duowan.title, 10), (duowan.author, 7))
duowan.suggest = (gen_suggests (DuowanType._doc_type.index, info_tuple))

to build a django search site
to create a new virtual environment
into the virtual environment and install django package pip install -i https://pypi.douban.com/simple/ django
then create a new django project with pycharm, direct running, you can see the server address in the log.
Then create a static directory, and paste in the css, html, js file, paste the html file to the templates directory.
Add a url in urls file

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from django.views.generic import TemplateView

= the urlpatterns [
path ( 'ADMIN /', admin.site.urls),
URL (R & lt '^ $', TemplateView.as_view (template_name = 'index.html'), name = 'index'),
]

was added in the settings line sets;

# Tuple herein can also be used with the tuple, then back to the path comma
STATICFILES_DIRS = [
the os.path.join (base_dir, 'static') can pass multiple #
]

In the index.html the <link href = "css / style . css "rel =" stylesheet "type =" import css text / css "/> and the like of the statement to a js

% Load staticfiles%} {
<head>
...
<Link the href = "{% static 'CSS / the style.css'%}" the rel = "this stylesheet" type = "text / CSS" />
... </ head >

This can static_url join the settings of the 'front of content, so that you can find html files.

Search suggestions
install the same version of es-dsl in a virtual environment
f fuzzy search
fuzzy:

The GET duowan / Video / _search
{
"Query": {
"Fuzzy": {
"title": {
"value": "Army Rider",
"fuzziness": 2,
"of prefix_length":. 3
}
}
},
"_Source": [ "title"]
}

fuzziness: edit distance
prefix_length: length in front of the word does not participate in the transformation of
"_source": [ "title" ]: indicates the field

suggest:

POST duowan/video/_search
{
"suggest": {
"my-suggest": {
"text":"PVQ",
"completion": {
"field": "suggest",
"fuzzy": {
"fuzziness":1
}
}
}
},
"_source": ["title"]
}

my-suggest可以自定义,field不能变,

Embedded in the index.html file in the js script, bound input event, when the inside of the content changes, send a request to the server, including input parameters content, type and type

$(function(){
$('.searchInput').bind(' input propertychange ',function(){
var searchText = $(this).val();
var tmpHtml = ""
$.ajax({
cache: false,
type: 'get', //get方法获取
dataType:'json',
url:suggest_url+"?s="+searchText+"&s_type="+$(".searchItem.current").attr('data-type'),
async: true,
success: function(data) {
for (var i=0;i<data.length;i++){
tmpHtml += '<li><a href="'+search_url+'?q='+data[i]+'">'+data[i]+'</a></li>'
}
$(".dataList").html("")
$(".dataList").append(tmpHtml);
if (data.length == 0){
$('.dataList').hide()
}else {
$('.dataList').show()
}
}
});
});
})

In the new urls:

URL (R & lt 'Suggest ^ / $', TemplateView.as_view (template_name = 'index.html'), name = 'index')
. 1
Models Django project and then copy the contents of file es-type crawler is to
re-edit file views:

import json
from django.shortcuts import render
from django.views.generic.base import View
from search.models import DuowanType
from django.http import HttpResponse


. # The Create your views here Wallpaper
# Inherited View
class SearchSuggest (View):
DEF GET (Self, request):
key_words = request.GET.get ( 's', '') # pass over the acquisition request with the default value of parameter s empty
re_dates = [] # to return to the saved search suggestions title
IF key_words:
S = DuowanType.search ()
# written query
S = s.suggest ( 'my_suggest', key_words, Completion = {
"Field": " Suggest ",
" Fuzzy ": {
" fuzziness ": 2
},
" size ": 10
})
# execute and get results
SUGGESTIONS s.execute_suggest = ()
for match in suggestions.my_suggest [0] .options:
Source = match. _Source
re_dates.append (Source [ 'title'])
# HttpResponse used to return results to the array to a return json
return HttpResponse(json.dumps(re_dates), content_type='application/json')

把urls中的

url(r'^suggest/$', TemplateView.as_view(template_name='index.html'), name='index')
改为

url(r'^suggest/$', SearchSuggest.as_view(), name='suggest')

Remember SearchSuggest.as_view (), not SearchSuggest.as_view, otherwise they will be given as follows:
TypeError: as_view () Takes 2 1 Positional argument But were GIVEN

Two search
urls in:

Import SearchSuggest search.views from, the SearchView
...
URL (R & lt '^ Search / $', SearchView.as_view (), name = 'Search')

adding a SearchView (View) in the views:
receiving a query keyword pass over the page parameters and parameters,
to create a client connected to the server es, may be performed using client.search original statement to execute a query using client.search, taken out in the receiving list stored in the return to the value returned by the result, Finally, return to the page with render,
query time: client.search recording time before and after the run, do subtraction

from elasticsearch import Elasticsearch
from datetime import datetime
client = Elasticsearch(hosts='127.0.0.1')
.......
class SearchView(View):
def get(self, request):
key_words = request.GET.get('q', '')
pagesize = 10
page = request.GET.get('p', '')
try:
page = int(page)
except:
page = 1

# Client.search allows the same wording as the most primitive writing
body = {
"Query": {
"multi_match": {
"Query": key_words,
"Fields": [ "title", "author"]
}
},
"from" : (-Page. 1) * pageSize,
"size": pageSize,
the content back to the highlighted value will highlight # highlighted field into
"highlight": {
# want to be added to the list indicated html tag tag inside can write values wondering
"pre_tags": [ "<span class = 'keyword'>"],
"post_tags": [ "</ span>"],
"Fields": {
"title": {},
"Content ": {}
}
}
}
START_TIME = DateTime.Now ()
Response = Client.search(
index="duowan",
body=body
)
end_time = datetime.now()
= last_seconds (END_TIME-START_TIME) .total_seconds ()
# the minute regardless of the total number of pages has
total_nums Response = [ 'Hits'] [ 'Total']
IF (Page 10%)> 0:
page_nums = int (total_nums / 10 ) + 1'd
the else:
page_nums = int (Page / 10)
# configured array some values passed back to the HTML
hit_list = []
for HIT in Response [ 'Hits'] [' Hits']:
hit_dict {} =
IF 'title 'in HIT [' highlight ']:
hit_dict [' title '] = HIT [' highlight '] [' title '] [0]
the else:
# intercept length hit_dict [' title '] = hit [' _ source '] [' title '] [: 100
hit_dict [' title '] = HIT [' _ Source '] [' title ']
hit_dict [' len '] = HIT [' _ Source '] [' len ']
hit_dict['tag'] = hit['_source']['tag']
hit_dict['update_time'] = hit['_source']['update_time']
hit_dict [ 'author'] = HIT [ '_ Source'] [ 'author']
hit_dict [ 'playnum_text'] = HIT [ '_ Source'] [ 'playnum_text']
hit_dict [ 'URL'] = HIT [ '_ Source'] [ 'URL']
hit_list.append (hit_dict)
return the render (Request, 'and result.html', { 'Page': Page,
'total_nums': total_nums,
'all_hits': hit_list,
'key_words': key_words,
'page_nums': page_nums,
'last_seconds': last_seconds})

in the page:
find the item div, with {% for hit in all_hits%} <div> ... </ div> {% endfor%} used for loop, traversal pass over query results list all_hits. padding values in the page

{% for hit in all_hits %}
<div class="resultItem">
<div class="itemHead">
<a href="{{ hit.url }}" target="_blank" class="title">{{ hit.title }}</a>
<span class="divsion">-</span>
<span class="fileType">
<span class="label">分类:</span>
<span class="value">{{ hit.tag }}</span>
</span>
<span class="dependValue">
<span class="label">播放次数:</span>
<span class="value">{{ hit.playnum_text }}</span>
</span>
</div>
<div class="itemBody">

</ div>
<div class = "itemFoot">
<span class = "info">
<label> Site: </ label>
<span class = "value"> Bole online </ span>
</ span>
<span class = "info">
<label> time: </ label>
<span class = "value"> hit.update_time {{}} </ span>
</ span>
</ div>
</ div>
{% endfor% }

realize searches using js:
click on the search button when the trigger add_search () method to get keyword, and then KillRepeat () to search for records to heavy, duplicates removed the memory array to the browser localStorage, and then search for content display come out

// click on the search when the trigger
function add_search () {
var Val = $ ( "searchInput.") Val ();.
IF (val.length> = 2) {
// When click on the search button to re-
KillRepeat (val) ;
// after the array is stored in the deduplication browser localStorage
localStorage.search = searchArr;
// then searches and displays
MapSearchArr ();
}

window.location.href=search_url+'?q='+val+"&s_type="+$(".searchItem.current").attr('data-type')

}

MapSearchArr function () {
var tmpHtml = "";
var arrLen = 0
IF (searchArr.length> =. 5) {
arrLen =. 5
} the else {
arrLen = searchArr.length
}
// spliced into the contents of the array html content
for (var i 0 =; I <arrLen; I ++) {
tmpHtml + = '<A the href = "' '? Q =' + + + SEARCH_URL searchArr [I] + '">' + searchArr [I] + '</a>'
}
$ ( "MySearch .all-Search.") HTML (tmpHtml);.
}
// remove the de-duplication of previously searched record, and the search word in front of this
function KillRepeat (Val) {
var = 0 the kill;
for (var I = 0; I <searchArr.length; I ++) {
// determines whether the word is present in the historical search records
iF (Val searchArr === [I]) {
the kill ++;
}
}
iF (the kill <1) {// absence
// into the head of the queue
searchArr.unshift (val);
} else {// the presence
// delete the original value
removeByValue (searchArr, Val)
searchArr.unshift (Val)
}
}

Original: https: //blog.csdn.net/qq_40916110/article/details/87855502

Guess you like

Origin www.cnblogs.com/hanzeng1993/p/11280518.html