장고와 elasticsearch 검색 엔진 사이트 백엔드 기능을 달성하기 위해

첫째, 스마트 프롬프트 입력 상자 (들 인터페이스 제공)
유형 수정
{ "유형": "완료 당신이 제안 분야에서 매핑을 설정해야합니다을 "}
그래서 우리는 유형의 정의를 수정할 :
에 필드 유형을 추가 제안 다음 개체가 제시하는 할당 된 입력의 ES-DSL 소스 때문에 몇 가지 문제가있다, 그래서이 정의는 CustomAnalyzer 자신의 정의에 주어진하고 사용자 정의, ik_analyzer의 객체를 선언하고 있습니다 :

...
elasticsearch_dsl.analysis 수입 CustomAnalyzer에서 _CustomAnalyzer로

클래스 CustomAnalyzer (_CustomAnalyzer) :

get_analysis_definition DEF (자동) :
# 여기에 문제가 주어지고 단지 피하기 위해 아무것도하지 않고
반환 ()


# ik_max_word를 전달하여 사용자 객체를 선언 않는 경우
ik_analyzer CustomAnalyzer = ( 'ik_max_word' 필터 = '소'])


DuowanType 클래스 (에서 DocType) :
...
# 정의 제안은 자동 완성 기능을 수행하는 것입니다.
중 # ES-DSL 소스 때문에 몇 가지 문제가 존재하므로,이 정의는 자신에게 CustomAnalyzer를 정의하는 소정되고
제안 = 완료 (분석기 = ik_analyzer)

발생 제안 값
생성 검색 제안 save_to_es
인터페이스를 제안 생성함으로써 자신을 생성 구조.
클래스 전역 함수 항목 gen_suggests에 정의 된 인덱스 정보와 무게를 송신 info_tuple가 설정된 가중치를 생성하는데 사용되며, 반환 컨텐츠 스토리지 배열을 제안한다. 텍스트 문자열이 비어 있지 않으면 탐색 info_tuple, ES 구성의 인터페이스는 문자열을 구문 분석하기 위해 호출 한 다음 구조에 반환 할 필요가 대조되어 분석

DEF gen_suggests (지수 info_tuple) : #의 가중치 정보의 복수의 튜플이 전송 될 수 있고, 또한 수있다 순차적
# 문자열 검색 제안 생성 어레이
# 중량에 사용되는 () uesd_words = 세트
제안 = [] #를 복귀를
위한 텍스트, info_tuple 무게
텍스트 경우 : 부정적인 빈 문자열 #의
#은 ES의 문자열 구문 분석 인터페이스를 분석 호출
= es.indices.analyze (색인 = 인덱스, 단어를 분석 = 'ik_max_word는'있는 params = { '필터'[ '소'}, 본문 =)]
anylyzed_words = SET (R & [ "토큰"]에서 R & LT 단어 LT [ "토큰"] (R & LT [ "토큰"] 렌 IF)이>. 1) 하나의 단어를 필터링하는 데 사용 #
new_words = anylyzed_words -에 uesd_words # 무게를
다른 :
new_words = SET ()
new_words 경우 :
suggests.append가 ({ 'INPUT'목록 (new_words), '무게'무게})
반환 제안합니다

save_to_es에 그 함수를 호출 :

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

장고 검색 사이트 구축은
새로운 가상 환경을 만들 수있는
가상 환경에와 장고를 설치 -i https://pypi.douban.com/simple/ 장고를 설치 PIP 패키지
다음 pycharm, 직접 실행으로 새로운 장고 프로젝트를 생성, 당신은 로그에 서버 주소를 볼 수 있습니다.
그런 다음 정적 디렉토리를 생성하고, CSS, HTML, JS 파일에 붙여 넣기, 템플릿 디렉토리에 HTML 파일을 붙여 넣습니다.
URL을 파일에 URL을 추가

django.contrib 수입 관리자에서
django.urls에서 경로 가져
django.conf.urls 가져 오기 URL에서를
django.views.generic 수입 TemplateView에서

= urlpatterns [
패스 ( 'ADMIN /'admin.site.urls),
URL (R & LT '^ $'TemplateView.as_view (TEMPLATE_NAME = 'index.html을'), 이름 = '인덱스')
]

의 설정에 첨가 광고 세트;

# 튜플 여기서도 다시 경로 콤마로 튜플과 함께 사용할 수
STATICFILES_DIRS의 =
os.path.join (BASE_DIR '고정')은 여러 # 전달할 수
]

된 index.html의 <링크 HREF = "CSS / 스타일 . CSS는 "확인해 ="스타일 "유형 =" 수입 CSS 텍스트 / CSS "/>과 JS에 대한 문의 등

%로드 staticfiles %} {
<헤드>
...
<링크 href를 = "{% 정적 'CSS /를있는 style.css'%}"를 확인해 = "이 스타일 시트"유형 = "텍스트 / CSS"/>
... </ 헤드 >

당신은 HTML 파일을 찾을 수 있도록이는 내용의 '앞의 설정을 가입 static_url 수 있습니다.

검색 제안은
가상 환경에서 ES-DSL의 동일한 버전을 설치
퍼지 검색 F
퍼지 :

가져 오기 duowan / 비디오 / _search
{
"검색어": {
"퍼지": {
"제목": {
"값": "군대 라이더",
"흐릿한": 2,
"prefix_length와의":. 3
}
}
},
"_Source" [ "제목"]
}

번짐 편집 거리
prefix_length와는 : 단어 앞의 길이의 변화에 관여하지 않는
"_source"[ "제목" ] 필드를 나타낸다

제안 :

POST의 duowan / 비디오 / _search
{
"제안": {
"내-제안": {
"텍스트": "PVQ",
"완료": {
"필드": "제안",
"퍼지": {
"흐릿한": 1
}
}
}
},
"_source": [ "제목"]
}

내-제안可以自定义, 필드不能变,

입력을 포함하여, 컨텐츠 변경의 내부가 서버에 요청을 전송하여 JS 스크립트에서 index.html 파일, 바인딩 입력 이벤트에 포함 된 콘텐츠, 종류 및 유형 매개 변수

$ (함수 () {
. $ ( '. searchInput') 결합 ( "입력에 PropertyChange '함수 () {
VAR 검색 텍스트 = $ (이) .val ();
var에 tmpHtml를 =" "
$ 아약스 ({
캐시 : FALSE ,
유형 : '수'는方法获取얻을 //
'JSON': dataType와
URL : "S =". suggest_url +을 + 검색 텍스트 + "& s_type ="+ $ ( ". searchItem.current") ATTR ( '데이터 형' ),
비동기 : 사실,
성공 : 기능 (데이터) {
(VAR 위해 I = 0; i가 data.length입니다를 <; 내가 ++) {
tmpHtml + = '<LI> <A HREF = "'+ SEARCH_URL + + 'Q =?' 데이터 [내가] + ''> '+ 데이터 [내가] +'> </A> </ 리 '
}
(. 데이터 목록 "). HTML (" ") $"
$ ( ". 데이터 목록"). 추가 (tmpHtml을 );
경우 (data.length입니다 == 0) {
$ ( '. 데이터 목록'). 숨기기 ()
} 다른 {
$ ( '. 데이터 목록'). 쇼 ()
}
}
});
});
})

새로운 URL을에서 :

URL (R & LT는 TemplateView.as_view (TEMPLATE_NAME =) 'index.html을'이름 = '인덱스'^ / $ 추천 ')
. 1 개
모델 장고 프로젝트 다음 파일 ES 형 크롤러의 내용을 복사하는 것이다
재 편집 뷰 파일 :

수입 JSON
렌더링으로 가져올 django.shortcuts에서
django.views.generic.base 수입보기에서
search.models에서이 DuowanType 가져
django.http 가져 오기에서를 HttpResponse에


. # 여기에서의 바탕 화면 귀하의 의견을 작성
# 상속보기
클래스 SearchSuggest (보기) :
DEF (자체 요청) GET :
key_words = request.GET.get가 ( 'S', '')의 기본 값으로 인수 요청을 통해 # 패스 매개 변수의 빈
re_dates의 =은 [] # 저장된 검색 제안 제목으로 돌아갑니다
: key_words IF
S = DuowanType.search ()
# 서면 질의
S = s.suggest ( 'my_suggest', key_words, 완료 = {
"필드" " "제안
"퍼지 "{
"번짐 "2
},
"크기 ": 10
})
# 실행하여 얻을 결과
제안 s.execute_suggest = ()
: suggestions.my_suggest [0]에 일치의 .options
자료 = 매치. _Source의
re_dates.append (소스 [ '제목'])
복귀 JSON으로 배열에 결과를 반환하는 데 # HttpResponse에
HttpResponse에 (json.dumps (re_dates) CONTENT_TYPE = '애플리케이션 / JSON')를 호출

把된 URL을中的

URL (R, '^이 / $ 제안'TemplateView.as_view (TEMPLATE_NAME =) 'index.html을'이름 = '인덱스')
改为

URL (R = '제안', 이름을 SearchSuggest.as_view () ^이 / $ 제안 ')

다음과 같이 그렇지 않으면이 주어집니다 SearchSuggest.as_view (),하지 SearchSuggest.as_view을 기억
2 1 위! 인수를 취) (as_view 그러나 주어진 : 형식 오류를

두 검색
하는 URL :

가져 오기 SearchSuggest search.views SearchView에서
...
URL (R & LT '^ 검색 / $', SearchView.as_view (), 이름은 = '검색')

관점에서 SearchView (보기)를 추가 :
오버 쿼리 키워드 패스를 받고 페이지 매개 변수 및 파라미터는
, 서버 ES에 접속 된 클라이언트를 생성하는 결과가 반환하는 값을 반환에 저장된 상기 수신 목록에서 취출 client.search를 사용하여 쿼리를 실행 client.search 원래 명령을 사용하여 수행 될 수있다 마지막으로, 렌더링과 페이지로 돌아
질의 시간 : client.search 녹화 시간 전에 실행 한 후, 뺄셈을 할

elasticsearch 수입 Elasticsearch에서
날짜 가져 오기 날짜에서
클라이언트 = Elasticsearch (호스트 = '127.0.0.1')
.......
클래스 SearchView (보기) :
: 데프 (자체 요청) 얻을
key_words = request.GET.get를 ( ' Q ',' ')
페이지 크기 = 10
페이지 request.GET.get = ('P ',' ')
: 시도
페이지 = INT (페이지)
를 제외한 :
페이지 = 1

# Client.search 가장 원시적 기입 같은 문구 있도록
본체 = {
"쿼리"{
"multi_match"{
"쿼리"key_words를,
"필드": "제목", "저자"]
}
}
"에서" (-page 1.) * pageSize가이
"크기"pageSize가,
#를 강조한다 강조된 값에 다시 콘텐츠에 필드를 강조
"하이라이트"{
#리스트에 추가하고자하는 내부 HTML 태그 태그 지시 궁금 값을 쓸 수있다
[ "<스팬 클래스 ="키워드 ">", "pre_tags"
"post_tags": "</ 스팬>",
"필드"{
"제목"{}
"콘텐츠 ": {}
}
}
}
START_TIME = DateTime.Now ()
응답 = 클라이언트.검색 (
인덱스 = "duowan"
본체 = 본체
)
END_TIME datetime.now = ()
= last_seconds (END_TIME - START_TIME) .total_seconds ()
분에 관계없이 전체 페이지 번호 #를 갖는다
[ '히트'응답하여 = total_nums [ '전체']
IF (페이지 10 %)> 0 :
page_nums = INT (total_nums / 10 ) + +1
: 밖의
page_nums = INT (페이지 / 10)
에 표시되는 HTML로 다시 전달 # 구성된 어레이 일부 값
hit_list = []
: 답변 HIT [ '히트'] [ '히트'] 대한
hit_dict {} =
IF '제목 'HIT에서 ['반전 ']
hit_dict ['제목 '= HIT ['반전 '] ['제목 '] [0]
다른 :
# 절편 길이 hit_dict ['제목 '] 히트 = ['_ 소스 '] [' 표제 '] [100
hit_dict ['제목 '= HIT의 ['_ 소스 '] ['제목 ']
hit_dict ['렌 '] = HIT의 ['_ 소스 '] ['렌]
hit_dict [ '태그'] 히트 = '_ 소스'] [ '태그']
hit_dict [ 'UPDATE_TIME'] 히트 = '_ 소스'] [ 'UPDATE_TIME']
hit_dict [ '저자'] = HIT의 [ '_ 소스'] [ '저자']
hit_dict에게 [ 'playnum_text'] = HIT [ '_ 소스'] [ 'playnum_text']
hit_dict에게 [ 'URL'] = HIT [ '_ 소스'] 'URL']
hit_list.append (hit_dict)
(가) (렌더링 요청 반환 '과 result.html', { '페이지'페이지,
'total_nums'total_nums,
'all_hits'hit_list,
'key_words'key_words,
'page_nums' page_nums,
last_seconds}) : 'last_seconds'

페이지에서이 :
all_hits %의 히트에 대한 {%}와 항목 DIV를 찾을 <div> ... </ DIV> {% ENDFOR %} 루프에 사용 순회 이상 통과 쿼리 목록 all_hits 결과. 패딩 값을 페이지에

{all_hits %의 히트에 대한 %}
<DIV 클래스 = "resultItem">
<DIV 클래스 = "itemHead">
<a href="{{ hit.url }}" target="_blank"의 class="title"> {{ }} hit.title </a>을
<스팬 클래스 = "divsion"> - </ SPAN>
<스팬 클래스 = "의 fileType">
<스팬 클래스 = "레이블">分类</ SPAN>
<스팬 클래스 = "값 "> {{hit.tag}} </ SPAN>
</ SPAN>
<스팬 클래스 ="dependValue ">
<스팬 클래스 ="레이블 ">播放次数</ SPAN>
<스팬 클래스 ="값 "> {{ hit.playnum_text}} </ SPAN>
</ SPAN>
</ div>
<div 클래스 = "itemBody">

</ DIV>
<DIV 클래스 = "itemFoot">
<스팬 클래스 = "정보">
<레이블> 사이트 </ 라벨>
<스팬 클래스 = "값"> 나무의 줄기가 온라인 </ SPAN>
</ SPAN>
<스팬 클래스 = "정보">
<레이블> 시간 : </ 라벨>
<스팬 클래스 = "값"> hit.update_time {{}} </ SPAN>
</ SPAN>
</ DIV>
</ DIV>
{% ENDFOR % }

JS를 사용하여 검색을 실현 :
트리거 add_search () 메소드가 무거운에 기록을 검색 한 후 KillRepeat ()를 키워드를 얻고, 때 검색 버튼을 클릭, 중복은 브라우저 로컬 스토리지에 메모리 어레이를 제거하고 내용 표시를 검색 나와

// 검색 클릭하면 트리거
기능 add_search () {
VAR 브로 = $ ( "searchInput.") 발 ();
IF (val.length> = 2) {
// 검색 버튼을 클릭 재시기
KillRepeat (발)을 ;
// 배열은 로컬 스토리지 중복 제거 브라우저에 저장된 후
localStorage.search = searchArr;
// 다음 콘텐츠 검색 및 표시
MapSearchArr을 ();
}

window.location.href = SEARCH_URL + '? = Q'+ 발 + "및 s_type ="+ $ ( ". searchItem.current"). ATTR ( '데이터 유형')

}

MapSearchArr 함수 () {
var에 tmpHtml = "";
VAR arrLen = 0
IF (. searchArr.length> = 5) {
. arrLen = 5
}는 다른 {
arrLen = searchArr.length
}
// 배열 HTML 콘텐츠의 내용에 접합
용 (VAR의 난 = 0; I는 arrLen를 <; I는 ++) {
tmpHtml + = '<A href를 = "'? 'Q ='+ + + SEARCH_URL searchArr [I] + '"> </A>를'+ searchArr [I] + '
}
$ ( "MySearch .ALL-검색 할 수 있습니다.") HTML (tmpHtml);
}
//이 앞에 이전 검색 기록의 중복 및 검색 단어 제거
기능 KillRepeat (발을) {
var에 = 0 킬 (kill);
대 (VAR의 I = 0; I <searchArr.length; I ++) {
// 단어가 과거의 검색 기록 존재 여부를 판단
만약에 (브로 searchArr === [I]) {
킬 ++;
}
}
만약에 (킬 <1) {// 부재
// 큐의 헤드에
searchArr.unshift (발);
} 다른 {// 존재
// 원래 값의 삭제
removeByValue (searchArr, 발)
searchArr.unshift (발을)
}
}

원본 : HTTPS : //blog.csdn.net/qq_40916110/article/details/87855502

추천

출처www.cnblogs.com/hanzeng1993/p/11280518.html