Movable Type 備忘録

 ブログ内検索を高速化( jQuery 版 )

  • Jul082007
  • Vote:
    http://bizcaz.com/archives/2007/07/08-032049.php
  • Categories: Customize, jQuery
  • Tags:
  • Social Bookmark

こんばんわ^^

MovableType 4 で動作するプラグインを確認していて、「あれっ!? このプラグインって紹介したっけ!?」と思ってブログ内検索したら・・・ ・・・ ・・・使えないじゃんっ Σ( ̄Д ̄;) ガーン!!
わたしのサイトで使ってるブログ内検索が prototype.js を使ってるのすっかり忘れてて、今日まで気づかなかった bzbell です。

ということで、急きょこちらのブログ内検索を高速化で紹介した Prototype 版を jQuery で動作するよう作り直してみました。

まだ改善の余地ありですが、とりあえず機能は満たせてるのでご紹介です ( ̄∇ ̄)/

ディレクトリ構成

  1. http://●●●.com/
  2.   +-- js/
  3.   | +-- jquery/
  4.   | | +-- jquery.js
  5.   | | +-- jquery.ajax.js

設置の仕方

事前に jQuery を入手して上記ディレクトリ構成のようにアップロードしておきます。
jQuery is a new type of JavaScript library.

  1. まず XML データを新規作成します。
    以下のコードをコピペして、インデックス・テンプレートを新規作成してください。

    1. <?xml version="1.0" encoding="utf8"?>
    2. {
    3. data:[
    4. <MTEntries all="1">{
    5. title:"<$MTEntryTitle remove_html="1" encode_js="1"$>"
    6. ,link:"<$MTEntryLink$>"
    7. ,body:"<$MTEntryBody remove_html="1" encode_js="1"$><$MTEntryMore remove_html="1" encode_js="1"$><MTComments>【<$MTCommentAuthor remove_html="1" encode_js="1"$>】<$MTCommentBody remove_html="1" encode_js="1"$></MTComments>"
    8. },</MTEntries>
    9. {title:"",link:"",body:""}
    10. ]
    11. }

    その際、ファイル名を search_data.txt として、トップページと同じ場所に保存します。
    また、「インデックス・テンプレートを再構築するときに、このテンプレートを自動的に再構築する」オプションをチェックしたまま保存します。

    作成したら再構築してください。

  2. 次に jQuery にカスタマイズしたスクリプトをアップロードします。
    以下をコピペして jquery.ajax.js というファイル名で保存します。

    1. var jquery_loader = 'http://●●●/ajax-loader.gif';
    2. var json_search_data = 'http://●●●/search_data.txt';
    3. var json_search_keyword = '';
    4. var json_search_is_loaded = false;
    5. var json_search_entries;
    6.  
    7. function json_search_archive()
    8. {
    9.     var result_data = new Array();
    10.  
    11.     json_search_keyword = json_search_keyword.replace(/([\/\\\.\*\+\?\|\(\)\[\]\{\}\$\^])/g, "\\$1");
    12.     json_search_keyword = json_search_keyword.replace(/( +| +)/, ' ');
    13.     json_search_keyword = json_search_keyword.replace(/( | )$/, '');
    14.  
    15.     var keywords = json_search_keyword.split(/ | /);
    16.     var key = new Array();
    17.  
    18.     for (var i = 0;i < keywords.length;i++)
    19.     {
    20.         key[key.length] = new RegExp(keywords[i], "i");
    21.     }
    22.  
    23.     for (var i = 0;i < json_search_entries.length - 1;i++)
    24.     {
    25.         var is_match = true;
    26.  
    27.         for (var j = 0;j < key.length;j++)
    28.         {
    29.             var res_body = key[j].exec( json_search_entries[i].body );
    30.             var res_title = key[j].exec( json_search_entries[i].title );
    31.  
    32.             if (!res_body && !res_title)
    33.             {
    34.                 is_match = false;
    35.             }
    36.         }
    37.  
    38.         if (is_match)
    39.         {
    40.             result_data[result_data.length] = json_search_entries[i];
    41.         }
    42.     }
    43.  
    44.     var result_html = '';
    45.  
    46.     if (result_data.length == 0)
    47.     {
    48.         result_html = '一致しませんでした';
    49.     }
    50.     else
    51.     {
    52.         result_html = json_search_result_html(result_data, keywords);
    53.     }
    54.  
    55.     $('#search-content').css('height', 'auto')
    56.                         .css('background-image', 'none')
    57.                         .html(result_html);
    58. }
    59.  
    60. function json_search_result_html(result_data, keywords)
    61. {
    62.     var html = '<p id="search_notice" style="text-align:left;">※スペースでAND検索が出来ます。<br />検索結果(' + result_data.length + '件ヒット )</p><div class="module-content"><ul>';
    63.  
    64.     for (var i= 0;i < result_data.length;i++)
    65.     {
    66.         html += '<li><a href="' + result_data[i].link + '#search_word=' + json_search_keyword + '" target="_blank">' + result_data[i].title + '</a></li>';
    67.     }
    68.  
    69.     html += '</ul></div><p class="search_hide"><a class="imgbutton" href="javascript:void(0)" style="font-weight:bold;" onclick="clear_block(\'#search-content\')"><span>&raquo; CLOSE</span></a></p>';
    70.  
    71.     return html;
    72. }
    73.  
    74. function json_search()
    75. {
    76.     json_search_keyword = $('input#search_box').val();
    77.  
    78.     $('#search-content').html('')
    79.                         .css('height', '100px')
    80.                         .css('background', 'transparent url(' + jquery_loader + ') no-repeat center center');
    81.  
    82.     if (json_search_is_loaded)
    83.     {
    84.         json_search_archive();
    85.     }
    86.     else
    87.     {
    88.         $.ajax({url: json_search_data, type: 'GET', dataType: 'xml', timeout: 1500,
    89.             error: function() {
    90.                 $('#search-content').css('height', 'auto')
    91.                                     .css('background-image', 'none')
    92.                                     .html('Error loading XML document');
    93.             },
    94.             complete: function(xml) {
    95.                 var data_string = xml.responseText;
    96.  
    97.                 data_string = data_string.replace(new RegExp('<.*?>', "i"), '');
    98.                 json_search_entries = eval(data_string);
    99.  
    100.                 json_search_archive();
    101.  
    102.                 json_search_is_loaded = true;
    103.             }
    104.         });
    105.     }
    106. }
    107.  
    108. function clear_block(blockid)
    109. {
    110.     $(blockid).html('');
    111. }

    青い字の部分を各自の環境に合わせて変更します。
    ajax_loader.gif はこちらのAjax loading gif generatorで作成することができます。

    変更したらて、上記ディレクトリ構成のようにアップロードします。

  3. 最後にメインページなどのテンプレートを変更します。
    HTML ヘッダ(<head>~</head>)内に以下を追加します。

    1. <script type="text/javascript" src="http://●●●/js/jquery/jquery.js"></script>
    2. <script type="text/javascript" src="http://●●●/js/jquery/jquery.ajax.js"></script>

    青い字の部分を各自の環境に合わせて変更します。
    次に既存のブログ内検索を以下のタグと差し替えます。

    1. <form action="javascript:json_search();">
    2. <table><tr>
    3.     <td><input type="text" id="search_box" value="" /></td>
    4.     <td><input type="hidden" id="search_button" /></td>
    5. </tr></table>
    6. <div id="search-content"></div>
    7. </form>

    赤い字の部分に検索結果が表示されます。
    差し替えたら保存して再構築します。

以上で設置は完了です。
各自のサイトからエントリの検索して確認します。

基本的な動作はブログ内検索を高速化と同じなので参考にしてください。

あぁ~(´Д`;) もぅこんな時間だよ。
明日早いからもう寝ます。おやすみなさい。

 Trackback Pings(1)

from masa.under.jp [blog]

以前からしなきゃしなきゃと思っていたMT4への移行にようやくトライしました。 ...

 Comments(4)

#1: Posted by ( ̄- ̄=)あぁ・・・ @ July 30, 2008 [REPLY]
user-pic

はじめまして。
一年も前の記事にコメントしていいモノか迷いましたが・・・

検索結果の件数のページ繰りって出来ないでしょうか。
いろいろコネコネしてみたんですが、う~ん・・・

妙案があればご享受頂けませんでしょうか。
宜しくお願い致します。

#2: Posted by Author Profile Page bzbellから( ̄- ̄=)あぁ・・・への返信 @ July 30, 2008 [REPLY]
user-pic

>>1 ( ̄- ̄=)あぁ・・・ さん

こんばんわ^^

> 検索結果の件数のページ繰りって出来ないでしょうか。

わたしもこのブログ検索使ってたとき同じこと考えましたパチパチ
でも、わたしのサイトの場合サーバから転送するデータサイズが 3M 相当あったことで、データ転送だけでブラウザがヒーヒー言ってたのでやめちゃいましたグウグウ
でも以下のようにすれば実現可能と思ってます。


  1. サーバからデータをもらう。

  2. もらったデータから該当キーワードの検索を行う。またこの時点でエントリごとに配列にしておく。

  3. 表示件数( たとえば 10 件 )分を 1 ページとして、配列のインデックス( 最初は 0 ) + 表示件数を表示

という具合に、NEXT / PREV リンクを用意して配列のインデックス操作してあげれば可能かと思います。
たとえば、NEXT リンクがクリックされたらカレントインデックス + 表示件数( 10 件 、PREV リンクはカレントインデックス - 表示件数ってなかんじですねにこっ!

ざっくりと説明してみましたがどうでしょあせあせ

#3: Posted by ( ̄- ̄=)あぁ・・・からbzbellへの返信 @ July 31, 2008 [REPLY]
user-pic

>>2 bzbell さん
お忙しい中有難う御座います。

受け取るデータの部分でなんとかしようと思っていたのですが、
ひとまず教えて頂いた方法でうまく動作しました。

>でも、わたしのサイトの場合サーバから転送するデータサイズが 3M 相当あったことで、
そういえばbzbellさんのどこかのエントリーでそのようなことをおっしゃっていたことを思い出しました。

計測してみたところ、私のところでも2M程あった為、やはりちょっときついかなという気がしています。

何はともあれ有難う御座いました。

#bzbellさんのエントリは、いつも有益な情報で非常に勉強になります。
#無責任ないい方ですが、これからも頑張って下さい。

#4: Posted by Author Profile Page bzbellから( ̄- ̄=)あぁ・・・への返信 @ July 31, 2008 [REPLY]
user-pic

>>3 ( ̄- ̄=)あぁ・・・ さん

こんばんわ^^

> 計測してみたところ、私のところでも2M程あった為、やはりちょっときついかなという気がしています。

そうなんですよねぇ。
最初はあまりの速さにビックリでしたけど、だんだんと唯一のデメリット!? と思われるデータ転送が目立ってきたので途中で方向転換しちゃいましたあせあせすっごくいいと思うのですが。残念。

 Post a Comment

 

コメント用フィード