ジャンゴとelasticsearch検索エンジンサイトのバックエンド機能を実現します

まず、スマートプロンプトの入力ボックスには、(ESインターフェイスを提供)
型の変更
あなたがフィールドにマッピングを設定する必要がありますをお勧め:{「タイプ」:「完了 」}
だから私たちは、型の定義を変更したい:
フィールドタイプを追加:提案、 ES-DSLのソースので、いくつかの問題があるので、この定義は、オブジェクトが示唆するように割り当てられているで入力し、CustomAnalyzerの独自の定義に、与えられ、その後、カスタムのオブジェクトを宣言し、ik_analyzerされています。

...
_CustomAnalyzerとしてelasticsearch_dsl.analysisインポート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重量テキスト、:
負空の文字列#1:テキストIF
#コールESの文字列解析するインタフェースを分析
単語を= es.indices.analyze(インデックス=指数、アナライザ=「ik_max_word」、paramsは= {「フィルタ」:[ '小文字'}、本文=)]
anylyzed_words = SET(R&[ "トークン"]におけるR&LT単語のLT [ "トークン"(R&LT [ "トークン"] lenのIF)が> 1)は、単一の単語をフィルタリングするために使用#
new_words = anylyzed_words -へuesd_words#重量
他:
new_words = SET()
new_words IF:
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))

Djangoの検索サイトを構築するための
新しい仮想環境を作成するために、
仮想環境へとDjangoをインストール-i https://pypi.douban.com/simple/ジャンゴをインストールするPIPパッケージ
、その後pycharm、直接実行して新しいDjangoプロジェクトを作成するには、ログにサーバのアドレスを見ることができます。
次に、静的なディレクトリを作成し、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(テンプレート名= 'のindex.html')、名前= 'インデックス')は、
]

設定に加え行セット。

#のタプルは、本明細書に戻し経路コンマに、タプルでも使用することができる
= [STATICFILES_DIRS
os.path.join(BASE_DIR、「静的」)複数#を通過することができる
]

のindex.html <リンクのhref =「CSS /スタイルで 。 CSS「のrel =」スタイルシート「タイプ =」 インポートCSSのテキスト/ cssの「/>とJSへの文のように

%負荷staticfiles%} {
<HEAD>
...
<リンクのhref = "{%静的'CSS / style.cssに' %}" REL = "このスタイルシート"タイプ= "テキスト/ CSS" />
... </ヘッド>

あなたはhtmlファイルを見つけることができるように、これは、コンテンツの「前の設定に参加static_urlすることができます。

検索候補は、
仮想環境でES-DSLの同じバージョンをインストールする
あいまい検索F
ファジー:

GETの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 = ""
$のアヤックス({
キャッシュ:偽、
種類: '取得'、//获取メソッド取得
データ型: 'JSON'、
URL: "?S =" suggest_url + +検索テキスト+ "&s_type =" + $( "searchItem.current。")のattr( 'データ型'。 )、
非同期:真、
成功:関数(データ){
(VAR i = 0; iはdata.lengthを<; Iは++){
tmpHtml + = '<LI> <HREF = " '+ search_url + +' Q ='データ[I] + '"> '+データ[I] +' </a>の</ LI>'
}
$("データリスト")。HTML(" ")
$("データリスト」)。追加(tmpHtml );
もし(data.length == 0){
$( 'DataListコントロール')。隠す()
}他{
$('。DataListコントロール')。ショー()
}
}
});
});
})

新しいURLで:

URL(R&LTは、TemplateView.as_view(テンプレート名=「)のindex.html」、名前=「インデックス」「^ / $提案」)
。1つの
モデルDjangoプロジェクトをしてから、ファイルのES型クローラの内容をコピーすることはすることです
再編集ファイルビュー:

輸入JSON
django.shortcutsからレンダリングインポート
django.views.generic.baseインポートビューから
search.modelsからDuowanTypeをインポート
django.httpインポートからのHttpResponse


。#ここにあなたのビューを作成壁紙
#継承ビュー
クラスSearchSuggest(ビュー):
DEF GET(セルフ、リクエスト):
パラメータsのデフォルト値で取得要求を超える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(テンプレート名を= 'index.htmlを')、名前= 'インデックス')
改为

URL(R '^示唆/ $'、SearchSuggest.as_view()、名前= '提案')

:次のようにそうでない場合はそれらが与えられますSearchSuggest.as_view()、ないSearchSuggest.as_viewを、覚えておいてください
2 1位置引数を取ります)(as_viewしかし、与えられた:TypeError例外を

2つの検索
:内の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(ビュー):
:DEF(自己、リクエスト)を取得
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 [' lenは'] = HITの[' _ソース'] [' 'lenは]
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 CLASS = "resultItem">
<DIV CLASS = "itemHead">
<a href="{{ hit.url }}" target="_blank"のclass="title"> {{ hit.title}} </a>の
<スパンクラス= "divsion"> - </スパン>
<スパンクラス= "たfileType">
<スパンクラス= "ラベル">分类</スパン>
<スパンクラス= "値"> {{hit.tag}} </ span>を
</ span>の
<スパンクラス=" dependValue ">
<スパンクラス="ラベル">播放次数</スパン>
<スパンクラス="値"> {{ hit.playnum_text}} </スパン>
</スパン>
</ div>
<DIV CLASS = "itemBody">

</ DIV>
<DIV CLASS = "itemFoot">
<スパンクラス= "情報">
<ラベル>サイト:</ label>は
<スパンクラス= "値">ボレオンライン</ span>を
</ span>の
<スパンクラス= "情報">
<ラベル>時間:</ label>は
<スパンクラス= "値"> hit.update_time {{}} </スパン>
</スパン>
</ div>
</ div>
{%ENDFOR% }

JSを使用した検索を実現:
(検索ボタンの上にキーワードを取得するためのトリガadd_search()メソッドをクリックし、[KillRepeat)重いのレコードを検索し、重複がブラウザのlocalStorageにメモリアレイを削除して、コンテンツ表示の検索します抜けます

ときトリガー//検索をクリックして
、関数add_search(){
VARヴァル= $( "searchInput。")ヴァル();.
IF(val.length> = 2){
再して検索ボタンをクリックすると//
KillRepeat(ヴァル) ;
//配列を重複排除ブラウザのlocalStorageに格納された後
localStorage.search = searchArr;
//コンテンツを検索して表示
MapSearchArrを();
}

window.location.href = search_url + '?Q =' +ヴァル+ "&s_type =" + $( "searchItem.current")。ATTR( 'データ型')

}

MapSearchArr関数(){
VAR tmpHtml = "";
VAR arrLen = 0
(。searchArr.length> = 5){IF
arrLen = 5。
}他{
arrLen = searchArr.length
}
//配列HTMLコンテンツの内容にスプライシング
(VARのiについて0 =;私はarrLenを<; Iは++){
tmpHtml + = '<HREF = "'? 'Q =' + + + SEARCH_URL searchArr [I] + '"> </a>に' + searchArr [I] + ''
}
$( "MySearch .ALL-検索。")HTML(tmpHtml);.
}
//これの前に、以前に検索されたレコードの重複排除、および検索ワード削除
機能KillRepeat(ヴァルを){
VAR = 0キル。
用(VARのI = 0; I <searchArr.length; I ++){
//単語履歴検索レコードに存在するか否かを判断する
場合には(ヴァルsearchArr === [I]){
キル++;
}
}
IF(キル<1){//不在
//キューの先頭に
searchArr.unshift(ヴァル)。
}他{//存在
//元の値の削除
removeByValue(searchArr、ヴァル)
searchArr.unshift(ヴァル)を
}
}

オリジナルます。https://blog.csdn.net/qq_40916110/article/details/87855502

おすすめ

転載: www.cnblogs.com/hanzeng1993/p/11280518.html