読者です 読者をやめる 読者になる 読者になる

FutureInsight.info

AI、ビッグデータ、ライフサイエンス、テクノロジービッグプレイヤーの動向、これからの働き方などの「未来」に注目して考察するブログです。

Google Suggestの動作原理 3

パソコン・インターネット

一回書いたの消えちゃったけど、今日は最後まで。

    • -

こんな感じで、うごいてるんだぜ:

まずhtmlがInstallAC関数を呼び、システムを初期化する、、、これは興味深いコードだぜ、

var Jb="zh-CN|zh-TW|ja|ko|vi|";

Google SuggestはEnglishしかサポートしないっていってる一方で、しっかりJapanとかKoreaとかChinaとかを認識し、リクエストをハンドルしてるんだ。

installAC関数はもう一つのinstallACPart2って俺が名付けた関数を呼ぶ。この関数は俺たちが使っているブラウザがXMLHttpをサポートしているかを確認し、俺が"_completeDiv"って呼んでる変数を作るんだ。こいつは俺らがgoogleからデータを取得したときの、その推測した結果を持ってるんだけど、こいつは検索キー入力フィールドに完璧に収まる形でそいつらを並べるんだ、最初は表示されないけどな。
installACPart2関数はいくつかのKey downとかresizeとかのイベントハンドラもセットする。こいつが、動的にGooglに対してリクエストを行い、URLが生成されるってわけだ。

俺がmainLoopって呼んでる関数は、繰り返しJavaScriptで書かれたsetTimeout関数を呼ぶんだ、おもしれーことに、設計者はキーボードのイベントをハンドルするよりも、タイムアウトを設定する機構を組み込んだ。これがおせー通信環境でも、はえータイプを何とかするメカニズムってワケよ。(例えばよ、おれがタイムアウトが起きることなく、すばやく3文字を打ち込んだら、その後で、一回だけ、googleからデータを取得するわけよ。)
このmainLoopは検索キー入力フィールドが何か書き込まれたかどうかを常にチェックしてる、んで、もし書き込みがあったらまずそこに同じ文字が書き込まれていないか結果を調べて、そのあと、googleからデータを取得するわけだ。Google Suggestのコードでは、XMLHttpオブジェクトをサポートしていない古いブラウザでもクッキーとフレームレローディングを駆使して、このへんのことをうまくやるらしいぜ。(このへんはおれもまだ試してないけどな、、、)

callGoogle関数の実装は率直で簡単だ。俺でも、その流れを書けるぜ。
(例えば、俺がEnglish圏で、"fast bug"ってタイプしてたらよ)
http://www.google.com/complete/search?hl=en&js=true&qu=fast%20bug
その時、URLはこうなるだろ。で、イベント駆動型のcallback _xmlHttp.onchangeファンクションを呼ばれて、こいつは、googleからデータを取得するために、最初から最後までJavaScriptでかけちまうような単純な処理をする、で、こんな感じのものをよぶわけだ。

sendRPCDone(frameElement, "fast bug", new Array("fast bug track", "fast bugs", "fast bug", "fast bugtrack"), new Array("793,000 results", "2,040,000 results", "6,000,000 results", "7,910 results"), new Array(""));

このsendRPCDoneって関数はac.jsのファイルの中で定義されてるんだけどよ、こいつがmainLoopの中でうまく同期を行い、受け取った結果をキャッシュにぶち込み、_completeDivを作る、、、DIVは結果の配列であり、最終的に表示されるものなわけだ。

displaySuggestedList関数は、その結果を受け取って、表示のためのワンセットのDOM構造のDIVとSPANを動的に生成する、で、こいつが推測結果を表示する最終的な形ってわけだ。さっき場合だと、listの要素やデータ構造はこんな感じになる。(ここでは(x)がコード内での変数な。)

<br /> <DIV (u) - mousedown/mouseover/mouseout class="aAutoComplete"><br /> <SPAN (ka) class="lAutoComplete"><br /> <SPAN (ua) class="cAutoComplete"><br /> bug tracking<br /> </SPAN (ua)><br /> <SPAN (ea) class="dAutoComplete"><br /> 500,000 results<br /> </SPAN (ea)><br /> </SPAN><br /> </DIV (u)><br /> </plaintext></p><p>んで、最後にPa関数(こいつは満足できる名前じゃねーな)は推測結果をうけとったり、なんかキーが押されたりしたら(たぶんマウス関連のイベントも補足してると思うよ)まだ、打たれてねー文字に対して強調をかけるってわけだ。</p><p>いままで書いたものをみたら、あんたらは自分自身で完璧にコードを解読しようと思うかもしんない、、、そん時に、なんか質問でもコメントでもあったら教えてくれ。俺がタイプミスをなおしたり、変数とか関数の名前を変えるいい機会になるからよ。<br /> </p> <ul> <li> <ul> <li>-</li> </ul></li> </ul><p>うーん、俺自身にとっても興味深い内容でした。<br /> JavaScriptも一つのインターフェースの解決策として身につけたいです。</p><p>ではでは、疲れたのでこのへんで。</p> </div> <footer class="entry-footer"> <p class="entry-footer-section"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="gamella">gamella</span></span> <span class="entry-footer-time"><a href="http://futureinsight.info/entry/20041227/1104114000"><time data-relative datetime="2004-12-27T02:20:00Z" title="2004-12-27T02:20:00Z" pubdate class="updated">2004-12-27 11:20</time></a></span> </p> <div class="hatena-star-container"> </div> <div class="hatena-star-metadata" style="display: none"> <a class="hatena-star-permalink" href="http://futureinsight.info/entry/20041227/1104114000">Google Suggestの動作原理 3</a> </div> <div class="social-buttons"> <div class="social-button-item"> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/20041227/1104114000" class="hatena-bookmark-button" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="http://futureinsight.info/entry/20041227/1104114000"></div> </div> <div class="social-button-item"> <a href="https://twitter.com/search?q=http%3A%2F%2Ffutureinsight.info%2Fentry%2F20041227%2F1104114000" class="social-button-twitter-balloon" target="_blank"> <span class="social-button-twitter-balloon-list">list</span> <i class="social-button-twitter-balloon-arrow-border"></i> <u class="social-button-twitter-balloon-arrow"></u> </a> <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://futureinsight.info/entry/20041227/1104114000" data-count="vertical" data-text="Google Suggestの動作原理 3 - FutureInsight.info" data-lang="ja">Tweet</a> </div> <div class="social-button-item"> <div class="g-plusone" data-size="tall" data-href="http://futureinsight.info/entry/20041227/1104114000"></div> </div> <span> <script type="text/javascript" src="//media.line.me/js/line-button.js?v=20140411" ></script> <script type="text/javascript"> new media_line_me.LineButton({"pc":false,"lang":"ja","type":"e"}); </script> </span> <div class="social-button-item"> <a data-pocket-label="pocket" data-save-url="http://futureinsight.info/entry/20041227/1104114000" data-pocket-count="vertical" class="pocket-btn" data-lang="en"></a> </div> </div> <div class="customized-footer"> <div class="entry-footer-html"><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- hatena-bottom2 --> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-8316025729440240" data-ad-slot="8180944571"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- hatena-bottom3 --> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-8316025729440240" data-ad-slot="9657677773"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></div> </div> <!-- enjapan ad --> </footer> </div> </article> <!-- rakuten_ad_target_end --> <!-- google_ad_section_end --> <div class="permalink pager"> <span class="pager-prev"> <a href="http://futureinsight.info/entry/20041227/1104115995" rel="prev"> <span class="pager-arrow">&laquo; </span> Google Suggestの動作原理 まとめ </a> </span> <span class="pager-next"> <a href="http://futureinsight.info/entry/20041226/1104068098" rel="next"> 帰省日記 <span class="pager-arrow"> &raquo;</span> </a> </span> </div> </div> </div> <aside id="box1"> <div id="box1-inner"> </div> </aside> </div><!-- #wrapper --> <aside id="box2"> <div id="box2-inner"> <div class="hatena-module hatena-module-recent-entries "> <div class="hatena-module-title"> <a href="http://futureinsight.info/archive"> 最新記事 </a> </div> <div class="hatena-module-body"> <ul class="recent-entries hatena-urllist urllist-with-thumbnails"> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <a href="http://futureinsight.info/entry/2016/11/02/192022" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title ">近況報告とAlpacaで機械学習エンジニアを募集のお知らせ </a> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/2016/11/02/192022" class="bookmark-widget-counter"> <img src="https://b.hatena.ne.jp/entry/image/http://futureinsight.info/entry/2016/11/02/192022" alt="はてなブックマーク - 近況報告とAlpacaで機械学習エンジニアを募集のお知らせ" /> </a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <a href="http://futureinsight.info/entry/2016/06/10/224322" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title ">「人工知能ベンチャー企業が打ち出すテクノロジー/未来 Meet up 第1回」で発表します </a> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/2016/06/10/224322" class="bookmark-widget-counter"> <img src="https://b.hatena.ne.jp/entry/image/http://futureinsight.info/entry/2016/06/10/224322" alt="はてなブックマーク - 「人工知能ベンチャー企業が打ち出すテクノロジー/未来 Meet up 第1回」で発表します" /> </a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <a href="http://futureinsight.info/entry/2016/05/20/210349" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title ">フィンテック × AIのスタートアップAlpacaにJoinして1年たったので近況報告 </a> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/2016/05/20/210349" class="bookmark-widget-counter"> <img src="https://b.hatena.ne.jp/entry/image/http://futureinsight.info/entry/2016/05/20/210349" alt="はてなブックマーク - フィンテック × AIのスタートアップAlpacaにJoinして1年たったので近況報告" /> </a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <a class="urllist-image-link recent-entries-image-link" href="http://futureinsight.info/entry/2016/03/21/081754"> <img alt="AIブームの説明だけではなく、2030年に向けた思考実験の基盤を提供してくれる本「商品の詳細 人工知能は私たちを滅ぼすのか―――計算機が神になる100年の物語」" src="https://cdn.image.st-hatena.com/image/square/be3d0b51f7e88ed749bc7c9268f61329b58b8fcd/backend=imagemagick;height=40;version=1;width=40/http%3A%2F%2Fecx.images-amazon.com%2Fimages%2FI%2F51l7WGk3DGL.jpg" class="urllist-image recent-entries-image" title="AIブームの説明だけではなく、2030年に向けた思考実験の基盤を提供してくれる本「商品の詳細 人工知能は私たちを滅ぼすのか―――計算機が神になる100年の物語」" width="40"> </a> <a href="http://futureinsight.info/entry/2016/03/21/081754" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title ">AIブームの説明だけではなく、2030年に向けた思考実験の基盤を提供してくれる本「商品の詳細 人工知能は私たちを滅ぼすのか―――計算機が神になる100年の物語」 </a> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/2016/03/21/081754" class="bookmark-widget-counter"> <img src="https://b.hatena.ne.jp/entry/image/http://futureinsight.info/entry/2016/03/21/081754" alt="はてなブックマーク - AIブームの説明だけではなく、2030年に向けた思考実験の基盤を提供してくれる本「商品の詳細 人工知能は私たちを滅ぼすのか―――計算機が神になる100年の物語」" /> </a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <a class="urllist-image-link recent-entries-image-link" href="http://futureinsight.info/entry/2016/02/24/230443"> <img alt="リモートワークとAlpacaの新オフィスの話" src="https://cdn.image.st-hatena.com/image/square/72736e35b757fc52b44d23e2fd169df17f3d5a39/backend=imagemagick;height=40;version=1;width=40/http%3A%2F%2Fecx.images-amazon.com%2Fimages%2FI%2F41nDcp8X7fL.jpg" class="urllist-image recent-entries-image" title="リモートワークとAlpacaの新オフィスの話" width="40"> </a> <a href="http://futureinsight.info/entry/2016/02/24/230443" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title ">リモートワークとAlpacaの新オフィスの話 </a> <a href="http://b.hatena.ne.jp/entry/http://futureinsight.info/entry/2016/02/24/230443" class="bookmark-widget-counter"> <img src="https://b.hatena.ne.jp/entry/image/http://futureinsight.info/entry/2016/02/24/230443" alt="はてなブックマーク - リモートワークとAlpacaの新オフィスの話" /> </a> </div> </li> </ul> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-body"> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- --> <ins class="adsbygoogle" style="display:inline-block;width:300px;height:600px" data-ad-client="ca-pub-8316025729440240" data-ad-slot="1151589378"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-title">このブログについて</div> <div class="hatena-module-body"> <p>Tomoya Kitayama(@gamella)が運営している物欲系ブログ。書評からガジェット、テクノロジーからライフハックまでなんでもネタにします。書評・ガジェットレビューなどのご依頼はtkitayama(at)gmail.comまで。ただし、お受けできないこともあります。献本はご連絡のうえ、電子書籍でお願いいたします。</p> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-body"> Facebookページもやってます! <div class="fb-like-box" data-href="https://www.facebook.com/futureinsight.info" data-width="300" data-height="400" data-colorscheme="light" data-show-faces="true" data-header="true" data-stream="false" data-show-border="true"></div> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-body"> <a href="https://plus.google.com/110814829100595115485" rel="publisher">Google+</a>もやってます! <!-- --> <div class="g-page" data-href="//plus.google.com/u/0/110814829100595115485" data-rel="publisher"></div> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-body"> <a class="twitter-timeline" href="https://twitter.com/gamella" data-widget-id="461484675626586112">@gamella からのツイート</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> </div> </div> <div class="hatena-module hatena-module-entries-access-ranking" data-count="10" data-display_entry_category="0" data-display_entry_image="1" data-display_entry_image_size_width="50" data-display_entry_image_size_height="50" data-display_entry_body_length="0" data-display_entry_date="0" data-display_bookmark_count="1" data-source="access" > <div class="hatena-module-title"> 注目記事 </div> <div class="hatena-module-body"> </div> </div> <div class="hatena-module hatena-module-html"> <div class="hatena-module-title">ブログ内検索</div> <div class="hatena-module-body"> <form action="http://www.google.co.jp/cse" id="cse-search-box"> <div> <input type="hidden" name="cx" value="partner-pub-8316025729440240:5858639779" /> <input type="hidden" name="ie" value="UTF-8" /> <input type="text" name="q" size="30" /> <input type="submit" name="sa" value="検索" /> </div> </form> <script type="text/javascript" src="http://www.google.co.jp/coop/cse/brand?form=cse-search-box&amp;lang=ja"></script> </div> </div> <div class="hatena-module hatena-module-archive" data-archive-type="default" data-archive-url="http://futureinsight.info/archive"> <div class="hatena-module-title"> <a href="http://futureinsight.info/archive">月別アーカイブ</a> </div> <div class="hatena-module-body"> </div> </div> </div> </aside> </div> </div> </div> </div> <script type="text/javascript">!function(d,i){if(!d.getElementById(i)){var j=d.createElement("script");j.id=i;j.src="https://widgets.getpocket.com/v1/j/btn.js?v=1";var w=d.getElementById(i);d.body.appendChild(j);}}(document,"pocket-btn-js");</script> <script src="https://s.hatena.ne.jp/js/HatenaStar.js"></script> <script type="text/javascript" src="https://platform.twitter.com/widgets.js"></script> <script src="https://apis.google.com/js/platform.js" async defer> { lang: 'ja', "parsetags": "explicit" } </script> <script type="text/javascript" src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/react-with-addons.min.js?version=0.14.7"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/react-dom.min.js?version=0.14.7"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/jquery.min.js?version=1.12.3"></script> <script type="text/javascript" src="//cdn7.www.st-hatena.com/js/jquery/jquery-ui.1.10.0.custom.min.js"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/jquery.flot.js?version=0.8.3"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/jquery.flot.time.js?version=0.8.3"></script> <script id="hatenablog-js" data-env="production" type="text/javascript" src="https://cdn.blog.st-hatena.com/js/hatenablog.js?version=cd1f9198dc35c0f0e286d9febe791ea0" crossorigin="anonymous"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/texts-ja.js?version=cd1f9198dc35c0f0e286d9febe791ea0"></script> <script type="text/javascript">Hatena.Diary.GlobalHeader.init()</script> <script src="https://www.google.com/recaptcha/api.js" async defer></script> <div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/ja_JP/sdk.js#xfbml=1&appId=719729204785177&version=v2.7"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <script id="hatena-counter-script" type="text/javascript"><!-- hatena_counter_name = "gamella"; hatena_counter_id = "101"; hatena_counter_ref = document.referrer+""; hatena_counter_screen = screen.width + "x" + screen.height+","+screen.colorDepth; //--></script> <script type="text/javascript" src="http://counter.hatena.ne.jp/js/counter.js"></script> <noscript><img src="http://counter.hatena.ne.jp/gamella/101" border="0" alt="counter"></noscript> </body> </html>