<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>へびにっき &#187; cicindela</title>
	<atom:link href="http://wp.serpere.info/archives/tag/cicindela/feed" rel="self" type="application/rss+xml" />
	<link>http://wp.serpere.info</link>
	<description>樹上で暮らすヘビのように生きたい</description>
	<lastBuildDate>Sat, 04 Feb 2012 13:25:38 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>CakePHP用Cicindelaライブラリ</title>
		<link>http://wp.serpere.info/archives/1111</link>
		<comments>http://wp.serpere.info/archives/1111#comments</comments>
		<pubDate>Sun, 31 Jan 2010 14:21:43 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[cicindela]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1111</guid>
		<description><![CDATA[CakePHP から レコメンデーションエンジン Cicindela にアクセスするためのライブラリを公開しました。 http://github.com/tkyk/cakephp-cicindela 使い方はREADMEを読んでください。Cicindela本体のWeb APIとほとんど同じ構造なので、特に迷うことはないだろうと思います。 ちなみに Configure::read(&#8216;debug&#8217;) > 1 で実行すると、DboSourceと同じようにリクエスト情報が一覧表示されます。デバッグに便利です。こんな感じ： (cicindela) 2 request(s) NrURLStatusTook (ms) 1http://host/cicindela/recommend?set=pick&#038;op=for_item&#038;item_id=RubyHTTP/1.1 200 OK2887 2http://host/cicindela/recommend?set=pick&#038;op=for_item&#038;item_id=PHPHTTP/1.1 200 OK1346 &#8230;. 以下、このライブラリを作りながら考えたこと。 このライブラリはDataSource + Behaviorという2クラス構成になっている。最初はDataSourceだけでできるかと思っていたのだが、無理だった。現在のCakeのModelクラスは、DataSourceとDboSourceの関係で言うなら&#8221;DboModel&#8221;であって、非DboのDataSourceを扱うには適していない。 現在のModelが&#8221;DboModel&#8221;であるように、XXXSourceに対してはXXXModelが存在することが望ましい。CakePHP 1.3からはDataSourceがプラグイン化できるようなので、同時にModelのベースクラスを提供するようにすれば、ある程度は改善されると思う。ただそれでも結局（プラグインの）ユーザがいちいちクラスの継承関係に気を使わなければいけない点が煩わしい。理想を言うなら、1.非常に簡素なBaseModelクラスを用意する、2.DataSourceにモデル初期化用コールバックを設ける、3.初期化用コールバックにおいてBehaviorをattachする、DataSource固有の機能はBehaviorに実装する……という構成にできれば良いのではないか。]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1111%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FaU6A7R%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CakePHP%E7%94%A8Cicindela%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%22%20%7D);"></div>
<p>CakePHP から レコメンデーションエンジン Cicindela にアクセスするためのライブラリを公開しました。
</p>
<a href="http://github.com/tkyk/cakephp-cicindela">http://github.com/tkyk/cakephp-cicindela</a>
<p>
使い方はREADMEを読んでください。Cicindela本体の<a href="http://code.google.com/p/cicindela2/wiki/WebAPI">Web API</a>とほとんど同じ構造なので、特に迷うことはないだろうと思います。
</p>
<p>
ちなみに Configure::read(&#8216;debug&#8217;) > 1 で実行すると、DboSourceと同じようにリクエスト情報が一覧表示されます。デバッグに便利です。こんな感じ：
</p>
<table><caption>(cicindela) 2 request(s)</caption>
<tr><td>Nr</td><td>URL</td><td>Status</td><td>Took (ms)</tr></tr>
<tr><td>1</td><td>http://host/cicindela/recommend?set=pick&#038;op=for_item&#038;item_id=Ruby</td><td>HTTP/1.1 200 OK</td><td>2887</tr></tr>
<tr><td>2</td><td>http://host/cicindela/recommend?set=pick&#038;op=for_item&#038;item_id=PHP</td><td>HTTP/1.1 200 OK</td><td>1346</tr></tr>
</table>
<p>
&#8230;.<br />
以下、このライブラリを作りながら考えたこと。
</p>
<p>
このライブラリはDataSource + Behaviorという2クラス構成になっている。最初はDataSourceだけでできるかと思っていたのだが、無理だった。現在のCakeのModelクラスは、DataSourceとDboSourceの関係で言うなら&#8221;DboModel&#8221;であって、非DboのDataSourceを扱うには適していない。
</p>
<p>
現在のModelが&#8221;DboModel&#8221;であるように、XXXSourceに対してはXXXModelが存在することが望ましい。CakePHP 1.3からはDataSourceがプラグイン化できるようなので、同時にModelのベースクラスを提供するようにすれば、ある程度は改善されると思う。ただそれでも結局（プラグインの）ユーザがいちいちクラスの継承関係に気を使わなければいけない点が煩わしい。理想を言うなら、1.非常に簡素なBaseModelクラスを用意する、2.DataSourceにモデル初期化用コールバックを設ける、3.初期化用コールバックにおいてBehaviorをattachする、DataSource固有の機能はBehaviorに実装する……という構成にできれば良いのではないか。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1111/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cicindelaを使ったAjaxアプリケーションサンプル 2</title>
		<link>http://wp.serpere.info/archives/1103</link>
		<comments>http://wp.serpere.info/archives/1103#comments</comments>
		<pubDate>Sat, 09 Jan 2010 13:42:44 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[cicindela]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1103</guid>
		<description><![CDATA[ライブドア製レコメンデーション・エンジン Cicindela の動作を確かめるために、簡単なAjaxアプリケーションを作ってみました。 前回の続きです。 JavaScript: Logger Cicindela との連携部分を作る前に、簡単な Logger を作っておきます。ログの出力先には TEXTAREA 要素を想定しています。 var Logger = &#123; clear: function&#40;&#41; &#123; $&#40;'#log'&#41;.val&#40;&#34;&#34;&#41;; &#125;, append: function&#40;text&#41; &#123; var dom = $&#40;'#log'&#41;.get&#40;0&#41;; dom.value+= text + &#34;\n&#34;; dom.scrollTop = dom.scrollHeight; &#125; &#125;; Cicindela への入力 まずは入力部分から作っていきます。このアプリケーションにおいて必要な操作は「あるユーザがアイテムを選択した」、「あるアイテムをあるカテゴリに所属させる」の2つです。これらの操作を抽象化するために、Cicindela Web APIに対する Proxy となるオブジェクトを作ります。 var Cicindela = &#123; base: '/cicindela/', set: 'sample', _insert_op_url: function&#40;op, item&#41; [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1103%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Cicindela%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FAjax%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%202%22%20%7D);"></div>
<p>
ライブドア製レコメンデーション・エンジン <a href="http://labs.edge.jp/cicindela/">Cicindela</a> の動作を確かめるために、簡単なAjaxアプリケーションを作ってみました。
</p>
<p>
<a href="http://wp.serpere.info/archives/1101">前回</a>の続きです。
</p>
<h3>JavaScript: Logger</h3>
<p>
Cicindela との連携部分を作る前に、簡単な Logger を作っておきます。ログの出力先には TEXTAREA 要素を想定しています。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Logger <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    clear<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#log'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    append<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>text<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> dom <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#log'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        dom.<span style="color: #660066;">value</span><span style="color: #339933;">+=</span> text <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        dom.<span style="color: #660066;">scrollTop</span> <span style="color: #339933;">=</span> dom.<span style="color: #660066;">scrollHeight</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>



<h3>Cicindela への入力</h3>
<p>
まずは入力部分から作っていきます。このアプリケーションにおいて必要な操作は「<a href="http://code.google.com/p/cicindela2/wiki/WebAPI#%E3%80%8C%E3%81%82%E3%82%8B%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%8C%E3%81%82%E3%82%8B%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%9F%E3%80%8D">あるユーザがアイテムを選択した</a>」、「<a href="http://code.google.com/p/cicindela2/wiki/WebAPI#%E3%80%8C%E3%81%82%E3%82%8B%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%82%92%E3%81%82%E3%82%8B%E3%82%AB%E3%83%86%E3%82%B4%E3%83%AA%E3%81%AB%E6%89%80%E5%B1%9E%E3%81%95%E3%81%9B%E3%82%8B%E3%80%8D">あるアイテムをあるカテゴリに所属させる</a>」の2つです。これらの操作を抽象化するために、Cicindela Web APIに対する Proxy となるオブジェクトを作ります。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Cicindela <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    base<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/cicindela/'</span><span style="color: #339933;">,</span>
    set<span style="color: #339933;">:</span>  <span style="color: #3366CC;">'sample'</span><span style="color: #339933;">,</span>
    _insert_op_url<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>op<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">base</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;record?set=&quot;</span><span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">set</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&amp;item_id=&quot;</span><span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&amp;op=&quot;</span><span style="color: #339933;">+</span> op<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    _send_req<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> cb<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Logger.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;send Request to &quot;</span> <span style="color: #339933;">+</span> url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;GET&quot;</span><span style="color: #339933;">,</span>
                 url<span style="color: #339933;">:</span> url<span style="color: #339933;">,</span>
                 success<span style="color: #339933;">:</span> cb<span style="color: #339933;">,</span>
                 complete<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>xhr<span style="color: #339933;">,</span> <span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                     Logger.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;receive Response[&quot;</span><span style="color: #339933;">+</span> xhr.<span style="color: #000066;">status</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;] from &quot;</span><span style="color: #339933;">+</span> url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                 <span style="color: #009900;">&#125;</span>
               <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    set_category<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">,</span> category<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>._send_req<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>._insert_op_url<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;set_category&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&amp;category_id=&quot;</span><span style="color: #339933;">+</span> category<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    insert<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>user<span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>._send_req<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>._insert_op_url<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;insert_pick&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&amp;user_id=&quot;</span><span style="color: #339933;">+</span> user<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
insert がアイテム選択、set_category がカテゴリ登録のためのメソッドです。実際にリクエスト送信を行うのは _send_req メソッドで、送信先URLと成功時に呼び出されるコールバック関数とを引数にとります。set プロパティには集計セットの名前を書いておいてください。
</p>
<p>
あとは「insert」ボタンが押されたときに、これらの API を呼び出します。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #006600; font-style: italic;">// $(document).ready において</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'button#insert'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span>
      <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> user_id <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#username'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>user_id <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>category_name<span style="color: #339933;">,</span> category_data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                   <span style="color: #003366; font-weight: bold;">var</span> category_id <span style="color: #339933;">=</span> category_data.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>
                   <span style="color: #003366; font-weight: bold;">var</span> container <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#&quot;</span><span style="color: #339933;">+</span> category_name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                   <span style="color: #003366; font-weight: bold;">var</span> values <span style="color: #339933;">=</span> container.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                   $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>values<span style="color: #339933;">,</span>
                          <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> v<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                              Cicindela.<span style="color: #660066;">set_category</span><span style="color: #009900;">&#40;</span>v<span style="color: #339933;">,</span> category_id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                              Cicindela.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span>user_id<span style="color: #339933;">,</span> v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                              $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#username'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                          <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
このアプリケーションの場合、カテゴリ登録はデータの初期化時にまとめて行った方が効率的なのですが、「同じアイテムを、何度同じカテゴリに登録しても問題ない」ことを確かめるために、あえてアイテム選択時に毎回登録を実行しています。
</p>
<p>
これで Cicindela への入力準備が整いました。ユーザ名を入力して、適当にアイテムを選択して「insert」ボタンを押してみます。成功すれば次のようなログが出力されるはずです。
</p>
<pre>
send Request to /cicindela/record?set=sample&#038;item_id=Ruby&#038;op=set_category&#038;category_id=1
send Request to /cicindela/record?set=sample&#038;item_id=Ruby&#038;op=insert_pick&#038;user_id=cicindela
receive Response[204] from /cicindela/record?set=sample&#038;item_id=Ruby&#038;op=insert_pick&#038;user_id=cicindela
receive Response[204] from /cicindela/record?set=sample&#038;item_id=Ruby&#038;op=set_category&#038;category_id=1
</pre>
<p>
またMySQLサーバにログインして、categories テーブルや picks テーブルにデータが入っていることを確認します。
</p>
<h3>Cicindela からの出力</h3>
<p>
続いて Cicindela からレコメンデーション・データを取り出してみます。必要なのは「<a href="http://code.google.com/p/cicindela2/wiki/WebAPI#%E7%89%B9%E5%AE%9A%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AC%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%28%E9%96%A2%E9%80%A3">特定アイテムに対するレコメンデーション(関連アイテム)取得 (=item to item)</a>」なので、次のような get_for_item メソッドを Cicindela オブジェクトに追加します。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> Cicindela <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* ...略... */</span>
&nbsp;
    get_for_item<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #339933;">,</span> category<span style="color: #339933;">,</span> cb<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">base</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">'recommend?set='</span><span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">set</span>
            <span style="color: #339933;">+</span><span style="color: #3366CC;">'&amp;op=for_item&amp;item_id='</span><span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&amp;category_id=&quot;</span><span style="color: #339933;">+</span> category<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>._send_req<span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> cb<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
そして「get」ボタンが押されたときにこのメソッドを呼び出します。第3引数として渡すコールバック関数は、正常にレスポンスが受信できたときに受信データを引数として呼び出されます。Cicindela からのレスポンスは改行区切りの文字列データです。ここでは単に出力用の要素に html メソッドで書き込んでおきます。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #006600; font-style: italic;">// $(document).ready において</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#get'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span>
      <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
          <span style="color: #003366; font-weight: bold;">var</span> item_id <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#items'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>category_name<span style="color: #339933;">,</span> category_data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                     Cicindela.<span style="color: #660066;">get_for_item</span><span style="color: #009900;">&#40;</span>item_id<span style="color: #339933;">,</span>
                                            category_data.<span style="color: #660066;">id</span><span style="color: #339933;">,</span>
                                            <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                                                $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#output-&quot;</span><span style="color: #339933;">+</span> category_name<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span>
                                            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                 <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
以上で一通りの機能が完成しました。ユーザ名と選択アイテムを変えて何度か入力を行い、レコメンデーションを取得してみましょう。その際には自分なりに”シナリオ”を決めて、そのシナリオに沿った結果になるか試してみると面白いです。例えば：「Perl好きはEmacsやVimを使う」、「WindowsユーザにもMacユーザにもLinuxユーザにもJava好きはいる」、「EmacsとVimを両方ともよく使うユーザは少ない」などなど。
</p>
<p>
完全なソースを gist に置いておきます。
</p>
<ul>
<li><a href="http://gist.github.com/272913">cicindela.html</a></li>
<li><a href="http://gist.github.com/272910">cicindela-sample.js</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1103/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cicindelaを使ったAjaxアプリケーションサンプル</title>
		<link>http://wp.serpere.info/archives/1101</link>
		<comments>http://wp.serpere.info/archives/1101#comments</comments>
		<pubDate>Thu, 07 Jan 2010 12:51:36 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[cicindela]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1101</guid>
		<description><![CDATA[ライブドア製レコメンデーション・エンジン Cicindela の動作を確かめるために、簡単なAjaxアプリケーションを作ってみました。スクリーンショット： 「好きなプログラミング言語」と「よく使うソフトウェア」についての情報を収集し、その結果に基づいておすすめの言語・ソフトを算出する、一種のアンケートです。 現実にはAjaxアプリケーションから直接 Cicindela のWeb APIを叩くのは難しいと思いますが（いたずらされ放題になってしまうので）、機能をテストするのには手軽です。以下に作り方を紹介しておきます。 Cicindela はセットアップ済みとします（CentOS 5にセットアップする手順はこちら） カテゴリー機能を使います アイテムid・ユーザidは文字列です jQuery 1.3.2 を使います Firefox 3で動作確認します（ほかのブラウザでも動くと思いますが） データベースの初期化 create_init_sql.pl を実行して使用するデータベースを作成します。DB名は sample としました。 perl create_init_sql.pl --db_name=sample &#124; mysql -uroot cicindelaの設定 lib/Cicindela/Config/_common.pm に集計セットを定義します。 'sample' =&#62; &#123; datasource =&#62; &#91; 'dbi:mysql:sample;host=localhost', 'cicindela', 'cicindela' &#93;, filters =&#62; &#91; 'PicksExtractor', 'InverseUserFrequency', 'ItemSimilarities', &#93;, recommender =&#62; 'ItemSimilarities::LimitCategory', refresh_interval =&#62; 1, [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1101%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Cicindela%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FAjax%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%22%20%7D);"></div>
<p>
ライブドア製レコメンデーション・エンジン <a href="http://labs.edge.jp/cicindela/">Cicindela</a> の動作を確かめるために、簡単なAjaxアプリケーションを作ってみました。スクリーンショット：
</p>
<p>
<a href="http://wp.serpere.info/wp-content/uploads/2010/01/cicindela.gif"><img src="http://wp.serpere.info/wp-content/uploads/2010/01/cicindela-300x266.gif" alt="Cicindela Ajaxアプリ" title="Cicindela Ajaxアプリ" width="300" height="266" class="size-medium wp-image-1102" /></a>
</p>
<p>
「好きなプログラミング言語」と「よく使うソフトウェア」についての情報を収集し、その結果に基づいておすすめの言語・ソフトを算出する、一種のアンケートです。
</p>
<p>
現実にはAjaxアプリケーションから直接 Cicindela のWeb APIを叩くのは難しいと思いますが（いたずらされ放題になってしまうので）、機能をテストするのには手軽です。以下に作り方を紹介しておきます。
</p>
<ul>
<li>Cicindela はセットアップ済みとします（<a href="http://wp.serpere.info/archives/1100">CentOS 5にセットアップする手順はこちら</a>）</li>
<li>カテゴリー機能を使います</li>
<li>アイテムid・ユーザidは文字列です</li>
<li>jQuery 1.3.2 を使います</li>
<li>Firefox 3で動作確認します（ほかのブラウザでも動くと思いますが）</li>
</ul>
<h3>データベースの初期化</h3>
<p>
create_init_sql.pl を実行して使用するデータベースを作成します。DB名は sample としました。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">perl</span> create_init_sql.pl --db_name=sample <span style="color: #000000; font-weight: bold;">|</span> mysql <span style="color: #660033;">-uroot</span></pre></div></div>



<h3>cicindelaの設定</h3>
<p>
lib/Cicindela/Config/_common.pm に集計セットを定義します。
</p>


<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">    <span style="color: #ff0000;">'sample'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
        datasource <span style="color: #339933;">=&gt;</span>  <span style="color: #009900;">&#91;</span> <span style="color: #ff0000;">'dbi:mysql:sample;host=localhost'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'cicindela'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'cicindela'</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        filters <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #ff0000;">'PicksExtractor'</span><span style="color: #339933;">,</span>
            <span style="color: #ff0000;">'InverseUserFrequency'</span><span style="color: #339933;">,</span>
            <span style="color: #ff0000;">'ItemSimilarities'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        recommender <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ItemSimilarities::LimitCategory'</span><span style="color: #339933;">,</span>
        refresh_interval <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
&nbsp;
        use_user_char_id <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        use_item_char_id <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        discard_user_id_char2int <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'6 month'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>



<p>
カテゴリ機能を使いたいので、フィルタとして ItemSimilarities を、レコメンダとして ItemSimilarities::LimitCategory を指定します。またユーザidとアイテムidに文字列を使用したいので、 use_*_char_id を設定します。結果を確認しやすくするために refresh_interval を 1 にしていますが、実運用時にはもっと大きな値を指定してください。
</p>
<h3>HTML</h3>
<p>
HTMLのbody内を抜粋すると次のようになります。SELECT 要素は後からJavaScriptで初期化するので、この段階では空っぽです。
</p>


<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>追加<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;insert&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>username: <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;username&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>好きな言語<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">multiple</span>=<span style="color: #ff0000;">&quot;multiple&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;langs&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/select<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>よく使うソフト<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">multiple</span>=<span style="color: #ff0000;">&quot;multiple&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;softs&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/select<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;submit-space&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;insert&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>insert<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>取得<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;recommend&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;select</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;items&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/select<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>おすすめ言語<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;output-langs&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>おすすめソフト<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/legend<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;output-softs&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;submit-space&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;button</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;get&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>get<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/button<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ログ<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h2<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;textarea</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;log&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/textarea<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>




<h3>JavaScript: データの定義</h3>
<p>
使用するデータは JavaScript のオブジェクトとして、次のような構造で定義します。langs と softs という2つのカテゴリがあり、それぞれに数値のid（1,2）が割り当てられています。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    langs<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
             list<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Perl'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'PHP'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Ruby'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Python'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Java'</span><span style="color: #339933;">,</span>
                    <span style="color: #3366CC;">'JavaScript'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'CSharp'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Erlang'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'CommonLisp'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    softs<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span>
             list<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'Windows'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Linux'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Mac'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Emacs'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Vim'</span><span style="color: #339933;">,</span>
                    <span style="color: #3366CC;">'Eclipse'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'NetBeans'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'VisualStudio'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'Dreamweaver'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>




<h3>JavaScript: SELECTの初期化</h3>
<p>
document の ready イベントにてSELECT要素を初期化します。Cicindela に渡す item_id としてアイテムの名前をそのまま使うので、OPTION要素の value 値にはアイテム名を設定しておきます。
</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>category_name<span style="color: #339933;">,</span> category_data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                 <span style="color: #003366; font-weight: bold;">var</span> all_items <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#items'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                 <span style="color: #003366; font-weight: bold;">var</span> category_items <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#&quot;</span><span style="color: #339933;">+</span> category_name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                 $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>category_data.<span style="color: #660066;">list</span><span style="color: #339933;">,</span>
                        <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span>l<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                            $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;option /&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'value'</span><span style="color: #339933;">,</span> l<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>l<span style="color: #009900;">&#41;</span>
                                .<span style="color: #660066;">clone</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>category_items<span style="color: #009900;">&#41;</span>
                                .<span style="color: #660066;">clone</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>all_items<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
             <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
続く。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1101/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CentOS 5にcicindelaをインストール</title>
		<link>http://wp.serpere.info/archives/1100</link>
		<comments>http://wp.serpere.info/archives/1100#comments</comments>
		<pubDate>Mon, 28 Dec 2009 15:15:15 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[cicindela]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1100</guid>
		<description><![CDATA[ライブドア製のレコメンデーションエンジン cicindela を CentOS 5.4 にインストールした記録です。極力 yum/rpm によるインストールを行うようにしています。参考にさせていただいたサイトははてブのcicindelaタグにまとめておきます。 cicindela ソースコードのチェックアウト Google Code でホストされている cicindela 本体のソースコードを /home/cicindela にチェックアウト。ここは公式の手順と全く同じなので、そちらを参照のこと。 Perlモジュールのインストール DBI/DBD-mysql は mysql-server を入れたら付いてくるので、その他のモジュールをrpmforgeから導入。公式サイトには書いていないが、私の環境では Class::Data::Inheritable と DBIx::ContextualFetch も必要だった。 sudo yum --enablerepo=rpmforge install \ perl-Ima-DBI \ perl-Time-Piece \ perl-Log-Log4perl \ perl-Module-Pluggable \ perl-Class-Singleton \ perl-Class-Data-Inheritable \ perl-DBIx-ContextualFetch ここで次のようなエラーが出た。 /usr/share/man/man3/Sys::Syslog.3pm.gz from install of perl-Sys-Syslog-0.27-1.el5.rf.i386 conflicts with file from package [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1100%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FcaAJE4%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CentOS%205%E3%81%ABcicindela%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%22%20%7D);"></div>
<p>
ライブドア製のレコメンデーションエンジン <a href="http://code.google.com/p/cicindela2/">cicindela</a> を CentOS 5.4 にインストールした記録です。極力 yum/rpm によるインストールを行うようにしています。参考にさせていただいたサイトは<a href="http://b.hatena.ne.jp/serpere/cicindela/">はてブのcicindelaタグ</a>にまとめておきます。
</p>
<h3>cicindela ソースコードのチェックアウト</h3>
<p>
Google Code でホストされている cicindela 本体のソースコードを /home/cicindela にチェックアウト。ここは公式の<a href="http://code.google.com/p/cicindela2/wiki/Install#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88">手順</a>と全く同じなので、そちらを参照のこと。
</p>
<h3>Perlモジュールのインストール</h3>
<p>
DBI/DBD-mysql は mysql-server を入れたら付いてくるので、その他のモジュールをrpmforgeから導入。<a href="http://code.google.com/p/cicindela2/wiki/Install#perl_%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">公式サイト</a>には書いていないが、私の環境では Class::Data::Inheritable と DBIx::ContextualFetch も必要だった。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #660033;">--enablerepo</span>=rpmforge <span style="color: #c20cb9; font-weight: bold;">install</span> \
  perl-Ima-DBI \
  perl-Time-Piece \
  perl-Log-Log4perl \
  perl-Module-Pluggable \
  perl-Class-Singleton \
  perl-Class-Data-Inheritable \
  perl-DBIx-ContextualFetch</pre></div></div>



<p>
ここで次のようなエラーが出た。
</p>
<pre>
/usr/share/man/man3/Sys::Syslog.3pm.gz from install of perl-Sys-Syslog-0.27-1.el5.rf.i386 conflicts with file from package perl-5.8.8-27.el5.i386
</pre>
<p>
Log-Log4perl の依存パッケージとしてインストールされる perl-Sys-Syslog パッケージが、CentOS 5(RHEL5)標準の perl パッケージに含まれる Sys::Syslog のファイルと衝突するらしい。<a href="http://www.mail-archive.com/users@lists.rpmforge.net/msg01283.html">参考URL</a>。
仕方がないので Log::Log4perl だけは cpan コマンドでインストールした。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> cpan <span style="color: #660033;">-i</span> Log::Log4perl</pre></div></div>



<h3>MySQL のインストールと設定</h3>
<p>
MySQL をインストール。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">yum <span style="color: #c20cb9; font-weight: bold;">install</span> mysql-server</pre></div></div>



<p>
公式のインストールガイドには /home/cicindela/etc/mysql/my.cnf を /etc/my.cnf にコピーせよとあるが、この中にはかなり癖の強い設定が含まれているので、既存のサーバを流用する場合は要注意。というか、実質的には cicindela 専用サーバが必要になると考えた方が良いだろう。
</p>
<p>特に注目すべき設置項目は以下の4つ。</p>
<dl>
<dt>max_heap_table_size = 1024M</dt>
<dd>MEMORY テーブルの最大サイズ。cicindela は MEMORY テーブルに入力データを保存するため、それなりに大きなサイズが必要になる。実際のところ、どのくらいあれば十分と言えるのだろうか…。</dd>
<dt>innodb_log_file_size = 256M</dt>
<dd>この設定値を後から変更すると起動不能に陥る場合があるので注意。変更する場合は<a href="http://d.hatena.ne.jp/urekat/20090423/1240473193">こちらのサイト</a>を参考に。
</dd>
<dt>innodb_lock_wait_timeout = 1800</dt>
<dd>デッドロックと判断するためのタイムアウト。デフォルトは50秒なので、極端に長い。おそらくはバッチ処理の都合でこうなっているのだろう。</dd>
<dt>innodb_flush_log_at_trx_commit = 2</dt>
<dd>
この設定値がどの程度意味を持つものなのか、正直言って分からない。<a href="http://dev.mysql.com/doc/refman/5.1/ja/innodb-parameters.html#optvar_innodb_flush_log_at_trx_commit">MySQLリファレンス</a>によれば、値を2にすることで、『より良い性能』と引き換えに『OS のクラッシュか停電によって、最後の秒のトランザクションが消されてしまいます。 』とのこと。
</dd>
</dl>

<h3>cicindela 用データベースの作成</h3>
<p>
misc/create_init_sql.pl を実行して、DB初期化用SQLを生成する。このスクリプトで生成できるのは CREATE DATABASE文、CREATE TABLE文 さらに &#8211;grant_* オプションを指定することで GRANT文も生成できる。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> misc
<span style="color: #c20cb9; font-weight: bold;">perl</span> create_init_sql.pl --db_name=cicindela \
  --grant_user=cicindela \
  --grant_host=localhost \
  --grant_pass=cicindela_pass <span style="color: #000000; font-weight: bold;">|</span> mysql <span style="color: #660033;">-uroot</span></pre></div></div>




<h3>cicindela の設定</h3>
<p>
cicindela の設定ファイル lib/cicindela/lib/Cicindela/Config/_common.pm の中で最小限の設定を含む集計セットを定義する。ここでは pick という名前にした。datasource に指定するDB名やhost名は適宜変更のこと。
</p>


<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #0000ff;">$C</span><span style="color: #009900;">&#123;</span>SETTINGS<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #ff0000;">'pick'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
        datasource <span style="color: #339933;">=&gt;</span>  <span style="color: #009900;">&#91;</span> <span style="color: #ff0000;">'dbi:mysql:cicindela;host=localhost'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'cicindela'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'cicindela_pass'</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        filters <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span>
            <span style="color: #ff0000;">'PicksExtractor'</span><span style="color: #339933;">,</span>
            <span style="color: #ff0000;">'InverseUserFrequency'</span><span style="color: #339933;">,</span>
            <span style="color: #ff0000;">'ItemSimilarities'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        recommender <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ItemSimilarities'</span><span style="color: #339933;">,</span>
        refresh_interval <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
設定を変更したらApacheを再起動。error_log や logs/log.txt にエラーが出ていないことを確認しておく。
</p>
<h3>動作確認</h3>
<p>以下のようなURLにアクセスして、HTTPステータスコード204が返ることを確認。user_id や item_id を変えつつ何度かアクセスしておく。</p>
<pre>http://<host>/cicindela/record?set=pick&#038;op=insert_pick&#038;user_id=3&#038;item_id=23</pre>
<p>入力バッファテーブルにデータが入っていることを確認。</p>
<pre>
mysql> select * from picks_buffer;
+----+---------+--------------+---------+--------------+-----------+---------------------+
| id | user_id | user_char_id | item_id | item_char_id | is_delete | timestamp           |
+----+---------+--------------+---------+--------------+-----------+---------------------+
|  1 |       3 | NULL         |      23 | NULL         |         0 | 2009-12-25 17:28:03 |
|  2 |       3 | NULL         |      23 | NULL         |         0 | 2009-12-25 17:28:11 |
|  3 |       3 | NULL         |      23 | NULL         |         0 | 2009-12-25 17:28:29 |
|  4 |       3 | NULL         |      23 | NULL         |         0 | 2009-12-25 17:28:52 |
|  5 |       5 | NULL         |      23 | NULL         |         0 | 2009-12-28 13:24:00 |
|  6 |       5 | NULL         |      29 | NULL         |         0 | 2009-12-28 13:24:20 |
+----+---------+--------------+---------+--------------+-----------+---------------------+
6 rows in set (0.01 sec)
</pre>
<p>
手動で bin/flush_buffer.pl を実行。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>flush_buffer.pl</pre></div></div>



<p>入力バッファがクリアされ、一時データテーブルに入力されることを確認。</p>
<pre>
mysql> select * from picks_buffer;
Empty set (0.00 sec)

mysql> select * from picks;
+---------+---------+---------------------+
| user_id | item_id | timestamp           |
+---------+---------+---------------------+
|       3 |      23 | 2009-12-25 17:28:03 |
|       5 |      23 | 2009-12-28 13:24:00 |
|       5 |      29 | 2009-12-28 13:24:20 |
+---------+---------+---------------------+
3 rows in set (0.00 sec)
</pre>
<p>
次に bin/batch.pl を実行、集計結果を算出する。<strong>初回実行時には2回実行する必要がある。</strong>ある程度以上のデータが溜まっていないと算出されないので注意。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>batch.pl</pre></div></div>



<pre>
mysql> select * from item_similarities_online;
+----------+----------+------------------+
| item_id1 | item_id2 | score            |
+----------+----------+------------------+
|       23 |       25 | 1.58496250072116 |
|       25 |       23 |                0 |
+----------+----------+------------------+
2 rows in set (0.00 sec)
</pre>
<p>
最後に以下のようなURLにアクセスして、Web API経由でリコメンデーション・データを取得できることを確認。
</p>
<pre>

http://<host>/cicindela/recommend?set=pick&#038;op=for_item&#038;item_id=23

</pre>
<p>
以上で cicindela の最低限の動作は確認できた。
</p>
<h3>daemontools のインストール</h3>
<p>
次に flush_buffer.p と batch.pl の実行を自動化するため、daemontools をセットアップする。まず daemontools-toaster のSRPMを <a href="http://www.qmailtoaster.org/">http://www.qmailtoaster.org/</a> から取得して、ビルド＆インストール。
</p>
<pre>
rpmbuild --rebuild daemontools-toaster-0.76-1.3.6.src.rpm
rpm -Uvh daemontools-toaster-0.76-1.3.6.$ARCH.rpm
</pre>
<p>
cicindela のバッチスクリプトに対するシンボリック・リンク作成。
</p>
<pre>
sudo ln -s /home/cicindela/etc/service/cicindela_batch /service/
sudo ln -s /home/cicindela/etc/service/cicindela_flush_buffers /service/
</pre>
<p>
/etc/inittab の末尾に svscan の起動コードを追加。
</p>
<pre>
SV:123456:respawn:/command/svscanboot
</pre>
<p>
init に HUP シグナルを送ってinittabを読み込み直し、svscanを起動する。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #660033;">-HUP</span> <span style="color: #000000;">1</span></pre></div></div>



<p>
ps コマンド等で svscan, supervise プロセスが起動していることを確認しておく。
</p>
<p>
この状態でもう一度データの入力テストを行い、自動的に一次データ・計算結果が更新されることを確認。
</p>
<p>
このまま放っておくとどんどんログが肥大化していくので、ログローテーション用設定ファイル /etc/logrotate.d/cicindela を以下の内容で作成する。
</p>
<pre>
/home/cicindela/var/logs/log.txt {
  daily
  create 0666 root root
  rotate 2
}
</pre>
<p>
次はより実践的な構成でテストを行う予定。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1100/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

