<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>DQNEO起業日記</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/" />
    <link rel="self" type="application/atom+xml" href="http://dqn.sakusakutto.jp/atom.xml" />
    <id>tag:dqn.sakusakutto.jp,2010-06-14://5</id>
    <updated>2012-02-05T02:57:42Z</updated>
    <subtitle>ど素人プログラマの挑戦。</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 5.12</generator>

<entry>
    <title>coLinux+Ubuntu12.04で日本語キーボードに設定する方法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/02/colinux-ubuntu1204.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.582</id>

    <published>2012-02-05T02:42:36Z</published>
    <updated>2012-02-05T02:57:42Z</updated>

    <summary>coLinuxでUbuntu12.04を入れてみたら、&quot;speedlinux&quot;と...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="coLinux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Ubuntu" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[coLinuxでUbuntu12.04を入れてみたら、"speedlinux"とかいう変なドイツ語のUbuntuが入ってしまいました。<br />
<br />
一応使えるのは使えるのですが、coLinuxコンソール上ではキーボードの設定がおかしくて使いづらい(恐らく英語キーボードになってる)<br />

<pre><code># loadkeys jp106
/usr/bin/ckbcomp: Can not find file "symbols/jp106" in any known directory</code></pre>

試行錯誤の末、aptitudeを入れてconsole-dataを入れれば解決できることがわかりました。

<pre><code># apt-get install aptitude
</code></pre>

ここでメモリオーバーでcoLinuxが落ちた。<br />
colinux設定ファイルでメモリ割り当てをmem=128 →mem=256に増やしてcoLinuxを再起動したらいけました。<br />

<pre><code># aptitude install console-data
</code></pre>

これで、GUIっぽい赤い画面が出てきます。<br />
"Japanese"を選択できました！<br />
<br />
無事、キーボードが日本語配列になりました。<br />
<br />
ところが、~ (ニョロ)が入力できない・・<br />

<pre><code># loadkeys jp106</code></pre>

これで、~が入力できるようになりました！<br />

]]>
        
    </content>
</entry>

<entry>
    <title>[Emacs]How to fix: &quot;No rule to make target `/usr/lib/crt1.o&apos;, needed by `temacs&apos;. Stop&quot;</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/02/emacshow_to_fix_no_rule_to_mak.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.581</id>

    <published>2012-02-02T06:06:10Z</published>
    <updated>2012-02-02T06:10:12Z</updated>

    <summary>When you see this error while compiling ...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Emacs" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Ubuntu" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[When you see this error while compiling Emacs 23.4 on Ubuntu ,
<pre><code>No rule to make target `/usr/lib/crt1.o', needed by `temacs'. Stop</code></pre>

Just try this.

<pre><code>$ gcc -print-file-name=crt1.o
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o</code></pre>

<pre><code>$ ./configure --without-x --with-crt-dir=/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/
$ make
$ sudo make install</code></pre>

Enjoy! :)
 

]]>
        
    </content>
</entry>

<entry>
    <title>Ubuntu12.04にEmacs23.4をインストールする方法(ソースからコンパイル)</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/02/ubuntu1204emacs234.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.580</id>

    <published>2012-02-02T05:22:39Z</published>
    <updated>2012-02-02T06:02:40Z</updated>

    <summary>Emacs 23.4がリリースされていたので、早速コンパイル＆インストールしまし...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Emacs" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Ubuntu" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[Emacs 23.4がリリースされていたので、早速コンパイル＆インストールしました。<br />
<br />
<pre><code>sudo apt-get install gcc make  # 準備
wget ftp://ftp.ring.gr.jp/pub/GNU/emacs/emacs-23.4.tar.gz  # ソースをダウンロード
tar xvfz emacs-23.4.tar.gz  # 解凍
cd emacs-23.4
./configure --without-x --with-crt-dir=/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/
make   #  コンパイル
sudo make install   # インストール</code></pre>
<br />
--with-crt-dirオプションですが、これをつけないとエラーになりました。<br />
普通にconfigureしてmakeしたら下記のようなエラー。<br />
インストーラにバグがあるみたいです。
<pre><code>No rule to make target `/usr/lib/crt1.o', needed by `temacs'. Stop</code></pre>
<br />
下記コマンドでctr1.oの場所がわかります。<br />
ここで表示されたディレクトリ名を--with-crt-dir=の後ろに書けばいけると思います。

<pre><code>%  gcc -print-file-name=crt1.o
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o</code></pre>


<h5>参考(英語サイト)</h5>

<a href="http://comments.gmane.org/gmane.emacs.devel/140480">http://comments.gmane.org/gmane.emacs.devel/140480</a>]]>
        
    </content>
</entry>

<entry>
    <title>[Perl]ファイルの中身を置換するワンライナー</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/01/perl-sed-oneliner.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.579</id>

    <published>2012-01-14T18:56:20Z</published>
    <updated>2012-01-14T19:03:27Z</updated>

    <summary>ファイル内のfooをすべてpiyoに置換するにはこうします。 perl -pi ...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[ファイル内のfooをすべてpiyoに置換するにはこうします。

<pre><code>perl -pi -e 's/foo/piyo/g' file.txt</code></pre>
<br />
sedでやるならこう。

<pre><code>sed -i -e 's/foo/piyo/g' file.txt</code></pre>
   ]]>
        
    </content>
</entry>

<entry>
    <title>SSHでPermission denied (publickey,gssapi-keyex,gssapi-with-mic)の対処法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/01/sshpermission_denied_publickey.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.578</id>

    <published>2012-01-14T15:16:05Z</published>
    <updated>2012-01-14T17:17:28Z</updated>

    <summary>Linuxサーバを構築するときには、次のように設定するのがよいと言われています。...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ管理" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[Linuxサーバを構築するときには、次のように設定するのがよいと言われています。

<ul>
	<li>rootでのSSHログインを禁止</li>
	<li>sshでのパスワードログインを禁止。代わりに公開鍵認証を使う</li>
	<li>一般ユーザを作成する</li>
</ul>

つまるところ、<br />
<strong>一般ユーザで公開鍵認証でログイン、という方式のみ許可する</strong><br />
ということになります。<br />
<br />
さて、Amazon EC2でサーバを作成して、上記３つの設定を施して、いざ一般ユーザでSSHログインしようしたら、下記のようなエラーが出てしまいました。<br />
<br />
<pre><code>$ ssh -i ~/.ssh/my_private_key userfoo@ec2-12-34-56-78.ap-northeast-1.compute.amazonaws.com
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).</code></pre>
<br />
うむむ。。<br />
]]>
        <![CDATA[<br />
リモートサーバの /etc/ssh/sshd_config を編集して、
<pre><code>PermitRootLogin yes</code></pre>
にすると、rootログインはできます。<br />
<pre><code>$ ssh -i ~/.ssh/my_private_key root@ec2-12-34-56-78.ap-northeast-1.compute.amazonaws.com
→ログイン成功
</code></pre>
なぜ一般ユーザでログインできないのか。。。<br />

<h4>解決方法</h4>

<br />
数時間格闘してわかったのですが、リモートサーバのuserfooのホームディレクトリに公開鍵ファイル(/home/userfoo/.ssh/authorized_keys)を置いてなかったのが原因でした。<br />
<br />
リモートサーバのrootの公開鍵をコピーしたら解決しました。<br />
<br />
<pre><code>$ mkdir /home/userfoo/.ssh
$ su -
$ cp /root/.ssh/authorized_keys /home/userfoo/.ssh/
$ chown userfoo.userfoo /home/userfoo/.ssh/authorized_keys
$ chmod 0700  /home/userfoo/.ssh
$ chmod 0644  /home/userfoo/.ssh/authorized_keys</code></pre>


]]>
    </content>
</entry>

<entry>
    <title>CGIエラーの対処法 (2)No such file or directory: exec of /path/to/hoge.cgi failed</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/01/cgi_2no_such_file_or_directory.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.577</id>

    <published>2012-01-13T19:16:41Z</published>
    <updated>2012-01-14T13:05:08Z</updated>

    <summary>Apacheのエラーログで表題のようなエラーがある場合、CGIの１行目のシェバン...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[Apacheのエラーログで表題のようなエラーがある場合、CGIの１行目のシェバン(#!/usr/bin/perl)が間違っている可能性が高いです。<br />
<br />
#!/usr/bin/perl<br />
<br />
#!/usr/loca/bin/perl<br />
<br />
などいろいろな書き方があります。<br />
Perlのインストール場所がどこなのか、確認しましょう。<br />
<br />
コマンドラインからwhich perlとコマンドをうてば、Perlのインストール場所がわかります。<br />

<pre><code>$ which perl
/usr/local/bin/perl
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>CentOS6で「visudo: コマンドが見つかりません」の対処法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/01/centos6visudo.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.576</id>

    <published>2012-01-11T21:13:43Z</published>
    <updated>2012-01-11T21:21:02Z</updated>

    <summary>CentOS6で、visudoコマンドを実行しようとしたらコマンドが存在しません...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="CentOS" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[CentOS6で、visudoコマンドを実行しようとしたらコマンドが存在しませんでした。<br />
<br />
<pre><code># visudo
-bash: visudo: コマンドが見つかりません</code></pre>

しかも、yumでインストールしようとしてもパッケージが見つかりません。<br />
<br />
<pre><code># yum search visudo
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.pensativo.nl
 * epel: mirror.bytemark.co.uk
 * extras: centos.mirror.pensativo.nl
 * ius: pancks.sothatswhy.org.uk
 * updates: centos.mirror.pensativo.nl
Warning: No matches found for: visudo
No Matches found</code></pre>

<h4>visudoはsudoの中に</h4>
実は、sudoをインストールするとvisudoが使えるようになります。<br />
<br />
<pre><code># yum search sudo
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirror.pensativo.nl
 * epel: mirror.bytemark.co.uk
 * extras: centos.mirror.pensativo.nl
 * ius: pancks.sothatswhy.org.uk
 * updates: centos.mirror.pensativo.nl
============== N/S Matched: sudo ===================
sudo.x86_64 : Allows restricted root access for specified users</code></pre>
<br />
<pre><code># yum -y install sudo
# visudo
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>[bash] /etc/profileと/etc/bashrcの違いは？どう使い分けるべきか？</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2012/01/bash_etcprofileetcbashrc.html" />
    <id>tag:dqn.sakusakutto.jp,2012://5.575</id>

    <published>2012-01-11T19:56:57Z</published>
    <updated>2012-01-11T21:09:54Z</updated>

    <summary>/etc/profile ユーザがログインしたときに実行されます。 したがって、...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="Bash" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[<h5>/etc/profile</h5>

ユーザがログインしたときに実行されます。<br />
したがって、ログインシェル用の環境変数の設定などをしたい場合は、こちらに記述します。<br />

<h5>/etc/bashrc</h5>
シェルスクリプトを実行するときなどに使われます。<br />
ログイン以外のシェル用途で使いたい場合は、こちらを使います。<br />

]]>
        
    </content>
</entry>

<entry>
    <title>[PostgreSQL] 知らないと損！コメントに関するtips３つ</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/postgresql-comment.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.573</id>

    <published>2011-12-24T15:21:01Z</published>
    <updated>2011-12-24T15:26:57Z</updated>

    <summary>PostgreSQL Advent Calendar 25日目です。 /* ～ ...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[<a href="http://atnd.org/events/21994">PostgreSQL Advent Calendar</a> 25日目です。<br />
<br />
<h4>/* ～ */ で複数行にわたるコメント</h4>

SQLでコメントを書くとき、"--"を使うのはよく知られています。<br />
<br />
<pre><code>-- ここはコメントです。
-- ここもコメントです。</code></pre>
<br />
知らない人が結構いるのですが、/* ～ */ でブロックコメントを書くことができます。<br />
<br />
こちらのスタイルの方が、C/Java/Javascript/PHP と同じなのでプログラマに優しいと思います。<br />
これは標準SQL準拠です。<br />
<br />
<pre><code>/*
 ここはコメント
 ここもコメント
 ここまでコメント 
*/
</code></pre>
]]>
        <![CDATA[<h4>テーブルやカラムにコメントを設定する</h4>
CREATE TABLEするときに、一緒にコメントを設定しておくとハッピーになれます。<br />
<br />
<pre><code>COMMENT ON TABLE  members IS '会員テーブル';
COMMENT ON COLUMN members.id IS '会員ID';</code></pre>
<br />
コメントでは改行コードを含めることができます。<br />
これを使うと、説明的な長いコメントを書くことができます。<br />
ドキュメントをエクセルで残すよりも実用的なのでオススメです。<br />
<br />

<pre><code>COMMENT ON TABLE members  IS E'会員テーブル\n会員情報を格納するテーブルです。\n使い方はほげほげで、ふがふがに注意してください';</code></pre>

<h4>テーブルやカラムのコメントを見る</h4>
設定したコメントは、phpPgAdminやpgAdmin等で閲覧できます。<br />
<br />
psqlで見るときは下記のようにします。<br />
<br />
カラムのコメントを見る<br />
<pre><code>mydb=&gt; \d+ members
       テーブル &quot;public.members&quot;
 カラム | 型      |  修飾語  | ストレージ | 説明
--------+---------+----------+------------+------------
 id     | integer | not null | plain      | 会員ID
</code></pre>
<br />
テーブルのコメントを見る<br />
<pre><code>mydb=&gt; \dt+ members
                         リレーションの一覧
 スキーマ |    名前     |    型    |  所有者  | サイズ |    説明
----------+-------------+----------+----------+--------+------------
 public   | members     | テーブル | dqneo    | 16 kB  | 会員テーブル
                                                       : 会員情報を格納するテーブルです。
                                                       : 使い方はほげほげで、
</code></pre>


<h4>おわりに</h4>
こんな入門記事でPostgreSQL Advent Calendar2011のオオトリをしめくくってしまいました。。<br />
でもPostgreSQLの裾野を広げるには初心者対策が一番重要だと思います。<br />
<br />
メリークリスマス！！<br />


]]>
    </content>
</entry>

<entry>
    <title>MongoDBのベストプラクティス１０箇条</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodb_3.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.572</id>

    <published>2011-12-24T03:53:21Z</published>
    <updated>2011-12-24T06:53:37Z</updated>

    <summary>MongoDB Best Practicesという面白い記事があったので意訳して...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[<a href="http://www.engineyard.com/blog/2011/mongodb-best-practices/">MongoDB Best Practices</a>という面白い記事があったので意訳してみます。<br />
書いた人はEngine Yardという会社のひとです。<br />
(Amazon EC2でMongoDBを運用する場合を主に想定しているようです。)<br />
<br />

<h4>１．必ずレプリカセット(replica sets)を使いましょう</h4>
]]>
        <![CDATA[レプリカセットを使うと、自動フェイルオーバーにより可用性が向上します。<br />
プライマリーノードがダウンしても、セカンダリノードが自動でプライマリーに昇格して、システム全体は落ちなくてすみます。<br />
我々は、レプリカされていないMongoDBをサポートすることはありません。<br />
レプリカのコストが大きいなら、MongoDBをホストしてくれるサービス(<a href="http://www.mongohq.com/">MongoHQ</a>や<a href="https://mongolab.com/home">MongoLabs</a>)を検討しましょう。<br />
Engine Yardはこれらの会社と提携しています。<br />

<h4>２．常に最新バージョンを使いましょう</h4>
MongoDBは常に最新バージョンを使ってください。<br />
10gen(MongoDBの開発元)はリリースのたびにたくさんの修正を入れていて、それらはあなたのシステムをより円滑に稼働するのに役に立ちます。<br />
<a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes">バージョン2.0.x</a>ではパフォーマンス、同時実行、インデックス、バグ修正、圧縮コマンドなどについての大幅な改善がなされています。<br />
またシステムをアップサイズするのが格段にやりやすくなっています。<br />
もしまだバージョン1.6.3を使っているなら、今すぐアップグレードしてください。<br />


<h4>３．32bitマシンで稼働させないで</h4>
MongoDBは32bitシステムでは2.5GBのデータ制限があります。<br />
そのストレージエンジンは性能向上のためにmemory-mappded fileを使っているので、利用可能なメモリーアドレスと結びついています。<br />
Engin Yard Cloudでは、ラージンインスタンスの使用を推奨します。<br />
我々は64bitインスタンス上のMongoDBのみサポートします。<br />

<h4>４．ジャーナリング(journaling)は有効にしておこう</h4>
MongoDBはwrite-ahead journalingという機能があります。<br />
これによりクラッシュリカバリが可能になり、ノードの堅牢性が高まります。<br />
ジャーナリングをデフォルトで有効にすることを強くお勧めします。<br />


<h4>５．データファイルの置き場所に気を使いましょう</h4>
MongoDBのデータファイル(例：/data/db/)が、永続的なパーティション上にあることを確認しましょう。<br />
データファイルの置き場所はEBSにすることをお勧めします。<br />
(訳注：EC2内蔵の揮発性ディスクに置かない方がよいという意味か？)<br />

<h4>６．メモリにおさまるようにしましょう</h4>
データ(とインデックス）をメモリに収まるようにすることは、システム全体のパーフォマンスにおいて非常に重要です。<br />
もしあなたのシステムのpage faults数が増加している(訳注：OSのページキャッシュに乗らなくなること？)ようであれば、<br />
データサイズがRAMサイズより大きくなっている可能性が高いです。<br />
その場合２つの選択肢があります。MongoDBのサーバインスタンスを増強するか、シャーディングするかです。<br />
まずはインスタンス増強する方をお勧めします。<br />

<h4>７．負荷が上がったらスケールアップしましょう</h4>
もしあなたのイインスタンスのloadが65%を超える(訳注：Engin Yard用語と思われる)ようなら、スケールアップを検討しましょう。<br />
loadは平常時ではこの閾値以内に収まるようにするべきです。<br />
これはリカバリやスケールアウトのシナリオにも影響します。<br />
もしインスタンス増強する場合は、AWSは次のような増強行程を推奨しています。Large, Extra Large, High Memory 4XLです。<br />
我々は、EBSボリュームを増強することで遅延が少なくなることを確認済みです。<br />

<h4>８．シャーディングには要注意</h4>
シャーディングをする場合は、あなたのアプリケーションのデータアクセスパターンをしっかり把握しておくことが必要です。<br />
ちゃんと時間をとって、MongoDBのシャーディングがどのように動くのか、本当にそれがあなたに必要かを理解してください。<br />
そして、シャーディングキーを適切に選ぶことがパフォーマンスに影響することを忘れないでください。<br />
<br />
設定サーバ(Config servers)はシステム健全性にとって非常に重要です。<br />
シャード環境では最低３つの設定サーバが必要です。<br />
絶対に設定情報を消してはいけません。常に頻繁にバックアップをとりましょう。<br />
可能なら、/etc/hostsファイルを使って名前ベースでサーバを参照するようにしましょう。<br />
<br />
設定サーバは小さなプロセスですが、これも64bitインスタンスで稼働させる必要があります。<br />
３つのサーバを同一インスタンスで稼働させないでください！<br />


<h4>９．Mongo MMSでサービスをグラフ化して監視しましょう</h4>
まだ使ってないなら、<a href="https://mms.10gen.com/user/login">Mongo MMS</a>を使うことを検討しましょう。<br />
10genはこの製品を活発に開発中です。<br />
あなたのシステムの健全性を視覚的にチェックするのにとても役に立つでしょう。<br />
<br />
<h4>１０．MongoDBの各種資料をフォローしましょう</h4>
MongoDBはすごい速さで進化しています。<br />
最新の資料をチェックしましょう。<br />
<br />
<ul>
	<li>ドキュメント:<a href="http://www.mongodb.org/display/DOCS/Home">http://www.mongodb.org/display/DOCS/Home</a></li>
	<li>Google Group: <a href="http://groups.google.com/group/mongodb-user">http://groups.google.com/group/mongodb-user</a></li>
	<li>バグ:<a href="https://jira.mongodb.org/">https://jira.mongodb.org/</a></li>
	<li>ブログ:<a href="http://blog.mongodb.org/">http://blog.mongodb.org/</a></li>
</ul>
]]>
    </content>
</entry>

<entry>
    <title>MongoDB:MapReduceの手続きを外部jsファイルに保存して実行する方法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodbmapreducejs.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.571</id>

    <published>2011-12-23T16:34:07Z</published>
    <updated>2011-12-23T16:59:44Z</updated>

    <summary>MapReduceの処理は、はじめのうちはインタラクティブシェルで試行錯誤するこ...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[MapReduceの処理は、はじめのうちはインタラクティブシェルで試行錯誤することになると思います。<br />
<br />
しかしシェル上でコードを書く場合、繰り返し実行するのが不便だったり、コードをバージョン管理(Git/Subversion)システムにコミットできないとういデメリットがあります。
<br />
いろいろ試してみて手法が固まってきたら、JSコードをファイルとして保存した方がよいでしょう。<br />
<br />
例えば、アクセスログの時間帯別集計をするMapRedcue処理を、下記のようにJSファイルとして保存します。
<br />
]]>
        <![CDATA[<h4>MapReduce処理を外部ファイルとして保存する</h4>
<h5>ファイル名：count_by_hours.js</h5>

<pre><code>// accesslogを時間帯別に集計して、
// 結果を別コレクションに保存するMapReduce

//出力先コレクション名を定義
var colname = 'countbyhours'; 

// 自作ユーティリティ関数
var JSTDate = function (str) {  return ISODate(str + &quot;T00+09:00&quot;);  };

var getYMDH = function (d) {
    d.setSeconds(0);
    d.setMilliseconds(0);
    d.setMinutes(0);

    yyyy = d.getFullYear();
    mm = d.getMonth() + 1;
    dd = d.getDate();
    hh = d.getHours();

    mm = new Number(mm).zeroPad(2);
    dd = new Number(dd).zeroPad(2);
    hh = new Number(hh).zeroPad(2);

    return yyyy + '-' + mm + '-' + dd + ' ' + hh + ':00:00';
};

// 期間指定のクエリ
var query  = { &quot;timestamp&quot; : { &quot;$gte&quot; : JSTDate(&quot;2011-11-01&quot;), &quot;$lt&quot; : JSTDate(&quot;2011-11-02&quot;)  } };

// MapReduce処理
var m = function () { emit( getYMDH(this.timestamp), 1) };
var r = function(key,values) { return Array.sum(values); };

db.accesslog.mapReduce(m,r, { query : query , scope : getYMDH ,  out : {merge: colname} } );

</code></pre>

<h4>実行方法</h4>

<h5>Linux/UnixシェルからJSファイルを実行する</h5>
<br />
<pre><code>$ bin/mongo hostname/dbname  /home/dqneo/count_by_hours.js    </code></pre>
これをcrontabに登録しておけば、毎日バッチでMapReduceを行うことができます。<br />
通常はこちらのやり方がよいでしょう。<br />
<br />

<h5>Mongoシェル内からJSファイルを実行する</h5>
<br />
Mongoシェルにログインした状態で、外部JSファイルを実行することもできます。<br />
load()関数を使います。<br />
<pre><code>$ bin/mongo

&gt; load('/home/dqneo/count_by_hours.js');
</code></pre>
loadした瞬間にJSファイルが実行され、MapReduce処理が走ります。
<br />
<br />

思えば、MySQLやPostgreSQLにも似たような機能(外部SQLファイルの実行。OSシェルから呼び出したり、SQLプロンプトから呼び出したり)がありますね。<br />


]]>
    </content>
</entry>

<entry>
    <title>MongoDB:MapReduceでscopeを使って関数を渡す方法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodbmapreducescope.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.570</id>

    <published>2011-12-23T12:30:41Z</published>
    <updated>2011-12-23T13:00:41Z</updated>

    <summary>MapReduceでは、scopeオプションというのがあります。 これを使うと、...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[MapReduceでは、scopeオプションというのがあります。<br />
これを使うと、あらかじめ作った自作関数をmap,reduce内から使うことができます。<br />
<br />
利点は、

<ul>
	<li>map関数本体がすっきりする</li>
	<li>単体テストがやりやすくなる</li>
</ul>

<br />
以前紹介した「<a href="http://dqn.sakusakutto.jp/2011/12/mongodb_mapreduce_1.html">MongoDB : サルでもわかるMapReduceその２：ログの時間別集計を行う</a>」のアクセスログ集計を、scopeを使って実行してみます。<br />
<br />

]]>
        <![CDATA[<pre><code>var query  = { &quot;timestamp&quot; : { &quot;$gte&quot; : ISODate(&quot;2011-11-01T00:00:00+09:00&quot;), &quot;$lt&quot; : ISODate(&quot;2011-11-02T00:00:00+09:00&quot;) } };

// 自作関数をあらかじめ定義
var getYMDH = function (d) {

    // timestampを１時間単位に切り捨てる

    d.setSeconds(0);
    d.setMilliseconds(0);
    d.setMinutes(0);

    yy = d.getFullYear();
    mm = d.getMonth() + 1;
    dd = d.getDate();
    hh = d.getHours();

    if (mm &lt; 10) { mm = &quot;0&quot; + mm; }
    if (dd &lt; 10) { dd = &quot;0&quot; + dd; }
    if (hh &lt; 10) { hh = &quot;0&quot; + hh; }
    return yy + '-' + mm + '-' + dd + ' ' + hh + ':00:00';
};

var m = function () {
   emit(getYMDH(this.timestamp;), 1);
};

var r = function(key,values) {
    return Array.sum(values);
};

// scopeオプションで自作関数を渡す
db.accesslog.mapReduce(m,r, { query : query , scope : getYMDH ,  out : 'myresults' } );

// 実行結果をみる
db.myresults.find();
{ &quot;_id&quot; : &quot;2011-11-01 00:00:00&quot;, &quot;value&quot; : 7546 }
{ &quot;_id&quot; : &quot;2011-11-01 01:00:00&quot;, &quot;value&quot; : 2885 }
{ &quot;_id&quot; : &quot;2011-11-01 02:00:00&quot;, &quot;value&quot; : 823 }
{ &quot;_id&quot; : &quot;2011-11-01 03:00:00&quot;, &quot;value&quot; : 823 }
{ &quot;_id&quot; : &quot;2011-11-01 04:00:00&quot;, &quot;value&quot; : 590 }
{ &quot;_id&quot; : &quot;2011-11-01 05:00:00&quot;, &quot;value&quot; : 579 }
{ &quot;_id&quot; : &quot;2011-11-01 06:00:00&quot;, &quot;value&quot; : 1365 }
{ &quot;_id&quot; : &quot;2011-11-01 07:00:00&quot;, &quot;value&quot; : 3230 }
{ &quot;_id&quot; : &quot;2011-11-01 08:00:00&quot;, &quot;value&quot; : 4344 }
{ &quot;_id&quot; : &quot;2011-11-01 09:00:00&quot;, &quot;value&quot; : 5754 }
</code></pre>

これで、mapもreduceも１行で書けるようになりました！！

]]>
    </content>
</entry>

<entry>
    <title>MongoDBで、インタラクティブシェルの詳しい使い方を調べる方法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodb_2.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.569</id>

    <published>2011-12-23T11:41:44Z</published>
    <updated>2011-12-23T12:12:07Z</updated>

    <summary>MongoDBにはJavaScriptで動くインタラクティブシェルがあります。 ...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[MongoDBにはJavaScriptで動くインタラクティブシェルがあります。<br />
<br />
このシェルには、組み込みの変数やオブジェクトやメソッドがいろいろあるのですが、ヘルプやマニュアルにも書いてない便利なメソッドがたくさんあります。<br />
<br />
例えば、Array.sumというメソッドがあって、配列の合計を求めたりできます。<br />
]]>
        <![CDATA[
<pre><code>&gt; Array.sum([1,2,3,4,5]);
15
</code></pre>
<br />
shuffle,uniqueというのもあります。
<pre><code>&gt; Array.shuffle([1,2,3,4,5]);
[ 1, 5, 2, 4, 3 ]

&gt; Array.unique([1,2,3,3,2,1]);
[ 1, 2, 3 ]
</code></pre>

こういのも。

<pre><code>&gt; new Number(7).zeroPad(3)
001</code></pre>

他にもいろいろあります。<br />
<br />
下記のAPIドキュメントのページに全て載っています。<br />
一度見てみると意外な発見があって面白いのではないでしょうか。
<br />
<a href="http://api.mongodb.org/js/">MongoDB API Docs for js</a>]]>
    </content>
</entry>

<entry>
    <title>MongoDBで、サーバ側に関数を永続的に保存しておく方法</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodb_1.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.568</id>

    <published>2011-12-23T09:39:05Z</published>
    <updated>2011-12-23T10:02:50Z</updated>

    <summary>Mongo shellでは、ログアウト時に変数が破棄される MongoDBのsh...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[<h4>Mongo shellでは、ログアウト時に変数が破棄される</h4>
MongoDBのshell上でグローバル関数を定義しても、いちどshellから抜けてしまうと関数は破棄されます。<br />
<br />
<pre><code>$ ~/bin/mongo
&gt; var wa = function (a,b){return a+b ;} 
&gt; wa(2,3)
5
&gt; exit
bye
(この時点で関数waは消滅する)

$ ~/bin/mongo

&gt; wa(2,3)
Fri Dec 23 18:41:59 ReferenceError: wa is not defined (shell):1
(関数waはもう存在しない)
</code></pre>

<h4>サーバ側に関数を保存する方法</h4>
]]>
        <![CDATA[サーバ側に関数を保存するには、db.system.jsという特別なコレクションを使います。
<br />
<pre><code>&gt; db.system.js.save({_id:'wa', value:function (a,b){return a+b;}});
> exit
bye

(一度ログアウト)

$ ~/bin/mongo

&gt; db.system.js.findOne({_id:&quot;wa&quot;}).value(2,3);
5

(このままだと使いにくいので変数に割り当てる
&gt; var wa = db.system.js.findOne({_id:'wa'}).value
&gt; wa(2,3);
5</code></pre>
<br />
関数waがサーバ側で永続的に存在することが確認できました。<br />
<br />
なお、db.system.jsはコレクションなので、DBごとに別々に存在します。

<h4>参考</h4>
<ul>
	<li><a href="https://github.com/mongodb/mongo/blob/master/jstests/storefunc.js">https://github.com/mongodb/mongo/blob/master/jstests/storefunc.js</a></li>
	<li><a href="http://d.hatena.ne.jp/muddydixon/20110325/1301076643">mongodbのmapReduceのscopeで変数は渡せるけれど、関数を渡せない問題の回避策</a></li>
</ul>
]]>
    </content>
</entry>

<entry>
    <title>MongoDB : サルでもわかるMapReduceその２：ログの時間別集計を行う</title>
    <link rel="alternate" type="text/html" href="http://dqn.sakusakutto.jp/2011/12/mongodb_mapreduce_1.html" />
    <id>tag:dqn.sakusakutto.jp,2011://5.567</id>

    <published>2011-12-23T08:12:17Z</published>
    <updated>2011-12-23T12:59:24Z</updated>

    <summary>前回の記事「MongoDB : サルでもわかるMapReduce」では、MapR...</summary>
    <author>
        <name>DQNEO</name>
        
    </author>
    
        <category term="MongoDB" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://dqn.sakusakutto.jp/">
        <![CDATA[前回の記事「<a href="http://dqn.sakusakutto.jp/2011/11/mongodb_mapreduce.html">MongoDB : サルでもわかるMapReduce</a>」では、MapReduceを使った簡単な集計を行いました。<br />
今回はもう少し実用的なことをしてみましょう。

<h4>アクセスログを時間帯別に集計する</h4>

accesslogというコレクションに、下記のようにユーザのアクセスログがたまっているとします。
<br />
<pre><code>&gt; db.accesslog.find();
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000000&quot;), &quot;user_id&quot; : 141637, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:00.223Z&quot;) }
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000001&quot;), &quot;user_id&quot; : 141637, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:00.432Z&quot;) }
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000002&quot;), &quot;user_id&quot; : 115383, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:02.994Z&quot;) }
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000003&quot;), &quot;user_id&quot; : 190968, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:03.871Z&quot;) }
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000004&quot;), &quot;user_id&quot; : 160751, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:05.071Z&quot;) }
{ &quot;_id&quot; : ObjectId(&quot;4eed6c60ee5b36a552000005&quot;), &quot;user_id&quot; : 121768, &quot;timestamp&quot; : ISODate(&quot;2011-11-01T15:00:05.163Z&quot;) }
 </code></pre>
<br />
これを時間帯別に件数カウントしてみましょう。<br />
]]>
        <![CDATA[<br />
RDBMSでは下記のようなSQLになると思います。(PostgreSQLでの例)
<pre><code>SELECT
  to_char(timestamp, 'yyyy-mm-dd HH24'::text) AS ymdh  ,count(*)
FROM accesslog
WHERE  '2011-12-01' &lt;= timestamp AND timestamp &lt; '2011-12-02'
GROUP BY ymdh
ORDER BY ymdh
;
</code></pre>

<h4>MapReduceを実行する</h4>


<pre><code>// 日本標準時を扱うためのユーティリティ関数

var JSTDate = function (str) {  return ISODate(str + &quot;T00+09:00&quot;);  };


// 日付範囲指定で対象を絞る。
// このように一時変数に記憶させておくと便利。

var query  = { &quot;timestamp&quot; : { &quot;$gte&quot; : JSTDate(&quot;2011-11-01&quot;), &quot;$lt&quot; : JSTDate(&quot;2011-11-02&quot;) } };


// map関数を定義。

var m = function () {


   var getYMDH = function (d) {

      d.setSeconds(0);
      d.setMilliseconds(0);
      d.setMinutes(0);

      yy = d.getFullYear();
      mm = d.getMonth() + 1;
      dd = d.getDate();
      hh = d.getHours();

      if (mm &lt; 10) { mm = &quot;0&quot; + mm; }
      if (dd &lt; 10) { dd = &quot;0&quot; + dd; }
      if (hh &lt; 10) { hh = &quot;0&quot; + hh; }
      return yy + '-' + mm + '-' + dd + ' ' + hh + ':00:00';
   };

   emit(getYMDH(this.timestamp), {count:1});
};


// reduce関数を定義。

var r = function(key,values) {
    var result = { count: 0};
    values.forEach(function(value){
      result.count += value.count;
    });
    return result;
};


// mapReduceを実行。
// 結果は'myresults'というコレクションに保存されます。

db.accesslog.mapReduce(m,r, { query : query , out : 'myresults' } );


// 結果をみる

db.myresults.find();
{ &quot;_id&quot; : &quot;2011-11-01 00:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 7546 } }
{ &quot;_id&quot; : &quot;2011-11-01 01:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 2885 } }
{ &quot;_id&quot; : &quot;2011-11-01 02:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 823 } }
{ &quot;_id&quot; : &quot;2011-11-01 03:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 823 } }
{ &quot;_id&quot; : &quot;2011-11-01 04:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 590 } }
{ &quot;_id&quot; : &quot;2011-11-01 05:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 579 } }
{ &quot;_id&quot; : &quot;2011-11-01 06:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 1365 } }
{ &quot;_id&quot; : &quot;2011-11-01 07:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 3230 } }
{ &quot;_id&quot; : &quot;2011-11-01 08:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 4344 } }
{ &quot;_id&quot; : &quot;2011-11-01 09:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 5754 } }
{ &quot;_id&quot; : &quot;2011-11-01 10:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 8066 } }
{ &quot;_id&quot; : &quot;2011-11-01 11:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 9099 } }
{ &quot;_id&quot; : &quot;2011-11-01 12:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 12266 } }
{ &quot;_id&quot; : &quot;2011-11-01 13:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 12504 } }
{ &quot;_id&quot; : &quot;2011-11-01 14:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 7752 } }
{ &quot;_id&quot; : &quot;2011-11-01 15:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 7876 } }
{ &quot;_id&quot; : &quot;2011-11-01 16:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 6843 } }
{ &quot;_id&quot; : &quot;2011-11-01 17:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 6197 } }
{ &quot;_id&quot; : &quot;2011-11-01 18:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 5069 } }
{ &quot;_id&quot; : &quot;2011-11-01 19:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 8490 } }
has more

it
{ &quot;_id&quot; : &quot;2011-11-01 20:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 10966 } }
{ &quot;_id&quot; : &quot;2011-11-01 21:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 17013 } }
{ &quot;_id&quot; : &quot;2011-11-01 22:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 18394 } }
{ &quot;_id&quot; : &quot;2011-11-01 23:00:00&quot;, &quot;value&quot; : { &quot;count&quot; : 15914 } }
</code></pre>

ざっとこんな感じです。<br />


<h4>追記</h4>
もうちょっと簡単に書けることがわかりました。<br />
今回のような単純な件数カウント処理の場合は、map/reduceのvalueをただの数値にしてもよいでしょう。<br />
<br />
さらに、Array.sum()という組み込みメソッドを使えばreduceは１行でいけます。<br />
<br />
<pre><code>var m = function () {

   var getYMDH = function (d) {

     d.setSeconds(0);
     d.setMilliseconds(0);
     d.setMinutes(0);

     yy = d.getFullYear();
     mm = d.getMonth() + 1;
     dd = d.getDate();
     hh = d.getHours();

     if (mm &lt; 10) { mm = &quot;0&quot; + mm; }
     if (dd &lt; 10) { dd = &quot;0&quot; + dd; }
     if (hh &lt; 10) { hh = &quot;0&quot; + hh; }
     return yy + '-' + mm + '-' + dd + ' ' + hh + ':00:00';
   };

   emit(getYMDH(this.timestamp), 1);
};


var r = function(key,values) {
    return Array.sum(values);
};

db.accesslog.mapReduce(m,r, { query : query , out : 'myresults' } );

db.myresults.find();
{ &quot;_id&quot; : &quot;2011-11-01 00:00:00&quot;, &quot;value&quot; : 7546 }
{ &quot;_id&quot; : &quot;2011-11-01 01:00:00&quot;, &quot;value&quot; : 2885 }
{ &quot;_id&quot; : &quot;2011-11-01 02:00:00&quot;, &quot;value&quot; : 823 }
{ &quot;_id&quot; : &quot;2011-11-01 03:00:00&quot;, &quot;value&quot; : 823 }
{ &quot;_id&quot; : &quot;2011-11-01 04:00:00&quot;, &quot;value&quot; : 590 }
{ &quot;_id&quot; : &quot;2011-11-01 05:00:00&quot;, &quot;value&quot; : 579 }
{ &quot;_id&quot; : &quot;2011-11-01 06:00:00&quot;, &quot;value&quot; : 1365 }
{ &quot;_id&quot; : &quot;2011-11-01 07:00:00&quot;, &quot;value&quot; : 3230 }
{ &quot;_id&quot; : &quot;2011-11-01 08:00:00&quot;, &quot;value&quot; : 4344 }</code></pre>




]]>
    </content>
</entry>

</feed>

