Hatena::Groupbugrammer

蟲!虫!蟲!

Esehara Profile Site (by Heroku) / Github / bookable.jp (My Service)
過去の記事一覧はこちら

なにかあったら「えせはら あっと Gmail」まで送って頂ければ幸いです。
株式会社マリーチでは、Pythonやdjango、また自然言語処理を使ったお仕事を探しています

 | 

2011-10-19

[] DotCloud + Node.js + MongoDBブレーンストーミング用のWebアプリを作ってみる 02:23

というわけで作りました

f:id:nisemono_san:20111019022148p:image

Docker Cloud - Build, Ship and Run any App, Anywhere

使い方

 黒い枠のあたりがテキスト入力のところ。エンターで入力できます。

 あとは数字のところを押すと数字が上がっていって、[del]を押すと消えます。

 誰でも気楽に消せるので、気楽に消していってください。

趣旨

 最近の目標としては、このブログを毎日更新することだったりするわけで、「そういえば、何か欲しいアプリは無いかな」と考えてみたところ、「自分のブログ記事を考えるための、ブレーンストーミングにつかえるようなアプリが欲しいな」と思ったことがきっかけ。

 で、ブレーンストーミングとWebSocketってたぶん、相性がいいんだろうな、リアルタイムでガンガン追加されて、リアルタイムでガンガン消えていく様子が眺められたら、それはそれで面白そうだな、と思って作ってみた。だいたい、どういう風に作るべきか、というのはわかったので、一日くらいでサクッと作れた。

 誰かの参考になるかもしれないので、コードはGithubに公開しています。

 GitHub - esehara/PublicBrainOverflow: Node.js + MongoDB + CoffeeScript example

 あと、何か適当に書いて欲しいネタがあれば、上記に投稿すれば、適当に採用するのでよろしくお願いします。

Node.jsとかHerokuって何ですか

 socket.io + Node.js + CoffeeScript + Heroku でお気楽リアルタイムウェブサイト作成 - 蟲!虫!蟲! - #!/usr/bin/bugrammer

 を見てください。あ、そういえばもう少しちゃんとNode.jsを理解したい人なら、次のスライドとか便利かも。

 no title

そもそも、MongoDBとは何なのか

 恥ずかしいことに、そもそも俺はMongoDBについてあまり知らない。MongoDBNode.jsと相性が良かったりするのは、その操作がJavaScriptをベースにしていたり、あるいは内部のデータ構造がJSONで管理されているため、元々JavaScriptベースに作られたNode.jsの組み合わせがよかったりする、ということくらいしか知らない。

 では、具体的にMongoDBとは何か、ついて知るためにはどのエントリがいいかなというと、自分がわかりやすかったのは下の感じ。

 第31回 RubyistのためのMongoDB入門(1) :Ruby Freaks Lounge|gihyo.jp … 技術評論社

Ubuntuでのちょっとしたはまりごと

 MongoDBはフォルダごとに管理するみたいなことをやっているっぽくて、例えばデフォルトだと"/data/db"にアクセスしようとするのが難点かも。詳細はしたのような感じ。

 Kosei Kitahara’s Blog: ubuntu に mongodb をインストール - with pymongo / vs couchdb

MongoDBに繋ぐために、Mongooseを使う

 さて、MongoDBが具体的になんなのか、そしてそれがNode.jsで利用するとどう便利なのかはわかるとして、ただ生の状態で扱うのもかなりだるいので、Node.jsで利用する為のプラグインは無いのかな、というと、Mongooseというのがいい感じ。Mangooseについては下のサイトが参考になる。

  node.js から MongoDB にアクセス (Mongoose の紹介) - KrdLab's blog

 あと実際の使用例としては、次のサイトが参考になるかな。

 herokuでNode.jsを使ってchatアプリ その3(MongoDBを利用して、メッセージを永続化) - from scratch

 ただ、あんまり他のサイトが気にしていなかった、各クエリの固有IDの扱い方について、少しメモしておこうかなと。

MongoDBと固有IDの関係

 MongoDBでは、内部で固有IDを振り分けて管理しているようす(ObjectIdという奴)。で、それにアクセスするためには、その個別クエリに対して、"_id"でアクセスしてあげればいい。口で説明するよりは、ソースで説明した方が早いかな。

#--- 既存のエントリから取得
        if !err and docs.length != 0
            doc_number = docs.length
            for i in [0 .. doc_number - 1]
                message = JSON.stringify
                            post_id:docs[i]._id
                            text:docs[i].text
                            rate:docs[i].rate
                console.log(message)
                socket.emit "message",message
#--- 新しく個別エントリを取得
            BrainPost = mongoose.model "BrainPost"     
            post = new BrainPost()
            message = JSON.stringify
                            text:msg
                            rate:0
                            post_id:post._id                

 Mongooseが優秀だからこういう挙動になるのか、それともMongoDB自体がそういう挙動なのかはよくわかりませんが、新しくポストを登録したときでも、新しくidを振り分けてくれるので、「リアルタイムで更新したいんじゃー、でもMongoDBの内部IDも欲しいんじゃー!」というとき便利。

MongoDBアクセスしたらTypeErrorを吐いた!どうするんだ!

 ここはJavaScriptのいいところでもあり、悪いところ。

 JavaScriptの挙動自体が、定義されていない変数アクセスしようとすると、"Undefined"というのを渡して処理してしまうので、そこから変数の値を取り出そうとすると、TypeErrorが起きてしまう。Node.jsJavaScriptなので、上記のような挙動を行う。なので、Undefinedが返ってきたときは、焦らずに「余計な要素にアクセスしようとしていないか」と考える方がいい。例えば、ちょっと固有IDとの関係のときに説明したけれども、mongooseは

 BrainPost.find {},(err,docs)

 みたいな形でアクセスできる。"{}"が検索条件で、この場合何もないので、全ての検索条件を返す。次に"docs"は実際に見つかったモノが配列で入っている。で、このdocsは何も見つからなかったときも吐き出してくれるので、"docs.length"みたいな形で「ねえ、本当に見つかったの?実は何もないんじゃないの?」と問い返すのがベターなんじゃないかなと思ったり。

HerokuでMongoDBはカードを持っていないとダメです

 じゃあさっそく、HerokuでMongoDBを使ってみよう……と思ったところ、基本的にHerokuは、無料のAdd-onインストールしたくても、カード情報を預けないと利用が出来なかったりする。自分はカードを単純に持っていない。で、dotcloudを使おうと思ったのだけれども、登る障壁が高すぎる。

 DotCloud自体は、こことか参考にしたらいいと思う。

 DotCloudを試してみたら、10分でHello Worldが公開できた。 - かってぃのブログ | choilog [チョイログ]

 まず、Socket.ioなんだけど、これを操作しないと結構大変。参考としては次のようにやるといいと思う。

 dotcloudでsocket.io 0.7系のxhr-pollingを動かしてみる - すぎゃーんメモ

 CoffieScriptはこっち。

 Page not found · GitHub

 見比べていれば、だんだんと理解できるはず。この障壁を乗り越えたら、次はCoffeeScriptから直接起動をする設定。

 Labnotes

[program:node]
environment = NODE_ENV=production
command = /home/dotcloud/current/node_modules/.bin/coffee server.coffee
directory = /home/dotcloud/current

 そして、さらにMongoDBに繋ぎたければ、UserとPassWordを新しく設定しないといけない。言語はPHPだけど、下が参考になった。

 Presented by Mickey!!: 【やった】dotcloud/MongoDBを試す。そしてクライアント(php)から接続する。

 理由はよくわからないが、いまはバージョンがあがって、わざわざdotcloud deploy -tというコマンドを打ち込まなくても、一回コミットしてしまえば、できてしまう。

 具体的には、次のように設定していく。

$ dotcloud run hogehoge.data mongo
$ use admin
$ db.auth("root","pass")
$ db.addUser("hogehoge","pass")

 で、ユーザーを追加。ここから

$ dotcloud info hogehoge.data 

 で出てきた"mongodb:root:xxxxxxx@hogehoge:port/"みたいなアドレスの、root:xxxxあたりを、新規追加したユーザーにして、アクセス先のURLとして使用。書式的には"userid : password"。db.addUserで入力した奴ですね。結果として表示されるほうではない。正直、どこまで正しいのかわからない。もし動かなかったら、使うデータベースに移行してからユーザー設定をするのもいいんじゃないか。

 ここまで来たら、だいたい完成。dotcloudでは内部をgitファイルで管理しているので

$ git add .
$ git commit -m "hogehoge"
$ dotcloud push hogehoge 

 でアップロードして完成。おつかれさまでした。

 |