node.jsからmongodbを使ってみる

MongoDBのインストール

以下手順でインストール

$ cat /etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=0

$ sudo yum install mongo-10gen-server.x86_64 mongo-10gen.x86_64 --enablerepo=10gen

はじめはmongooseのみをインストールしていたため、nodeからMongoDBに接続ができなかった。

$ node feed.js

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: failed to connect to [localhost:27017]
    at null.<anonymous> (/home/vagrant/buzz/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:546:74)
    at EventEmitter.emit (events.js:106:17)
    at null.<anonymous> (/home/vagrant/buzz/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:150:15)
    at EventEmitter.emit (events.js:98:17)
    at Socket.<anonymous> (/home/vagrant/buzz/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:533:10)
    at Socket.EventEmitter.emit (events.js:95:17)
    at net.js:440:14
    at process._tickCallback (node.js:419:13)

エラー出力

[Error: failed to connect to [127.0.0.1:27017]]

mongooseはあくまでnode.jsで利用するMongoDBのドライバであり、MongoDBを別途インストールしてmongodプロセスが立ち上がっている必要があるようです。

プロセス確認

$ ps awux | grep mongod
vagrant   8823  0.0  0.1 103240   848 pts/0    S+   15:42   0:00 grep mongod

mongodbを起動

$ sudo /etc/init.d/mongod start
Starting mongod:                                           [  OK  ]

プロセスを再確認

$ ps awux | grep mongod
mongod    8858 11.4  5.5 467100 33616 ?        Sl   15:43   0:03 /usr/bin/mongod -f /etc/mongod.conf
vagrant   8887  0.0  0.1 103240   852 pts/0    S+   15:43   0:00 grep mongod

mongooseのインストール

node.jsからMongoDBにアクセスするためのライブラリ

$ npm install mangoose

ソースコード

RSSから取得してきたTitle, 日付, URLをtestdbというデータベースのbuzzwordsコレクションに格納する

feed.js

// feedparser - https://www.npmjs.org/package/feedparser
var FeedParser = require('feedparser')
    , request = require('request');

// Mongoose
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/testdb', function(err) {
    if (err) {
        console.log(err);
    }
});
// スキーマを作成
var buzzwordSchema = mongoose.Schema({
    name: String,
    date: Date,
    xmlurl: String
});
var Buzzword = mongoose.model('Buzzword', buzzwordSchema);

// RSS URL
var xmlurl = 'http://kizasi.jp/rss.xml';

var req = request(xmlurl)
    , feedparser = new FeedParser(); // new FeedParser([options])でoptions設定

req.on('error', function (error) {
    // リクエストエラー処理
});
req.on('response', function (res) {
    var stream = this;
    if (res.statusCode != 200) {
        return this.emit('error', new Error('Bad status code'));
    }
    stream.pipe(feedparser);
});

feedparser.on('error', function(error) {
    // 通常のエラー処理
});
feedparser.on('readable', function() {
    // 処理ロジックを書く
    // metaプロパティはfeedeparserインスタンスのコンテキストに常に置き換える
    var stream = this
        , meta = this.meta
        , item;

    // 取得したアイテムをMongoDBに保存
    var buzzword = new Buzzword();
    while (item = stream.read()) {
        buzzword.name = item.title;
        buzzword.date = item.date;
        buzzword.xmlurl = xmlurl;
        buzzword.save(function(err, buzzword) {
            if (err) {
                console.log(err);
            }
        });
    }
})

要点

MongoDBへの接続

mongoose.connect('mongodb://localhost/testdb', function(err) {
    if (err) {
        console.log(err);
    }
});

ドキュメントのスキーマを定義

var buzzwordSchema = mongoose.Schema({
    name: String,
    date: Date,
    xmlurl: String
});

ドキュメントに格納

var buzzword = new Buzzword()
buzzword.name = item.title;
buzzword.date = item.date;
buzzword.xmlurl = xmlurl;

MongoDBにデータを保存

buzzword.save(function(err, buzzword) {
    if (err) {
        console.log(err);
    }
});

MongoDBを確認

$ node feed.js
$ mongo
MongoDB shell version: 2.6.4
connecting to: test
> show dbs;
admin   (empty)
local   0.078GB
test    (empty)
testdb  0.078GB
> use testdb
switched to db testdb
> show collections;
buzzwords
system.indexes
> db.buzzwords.find()
{ "_id" : ObjectId("541076c801e48dfe238a6301"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "AppleWatch", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6302"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "iphone6", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6303"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "昭和天皇実録", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6304"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "チリッチ選手", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6305"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "ベネズエラ戦", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6306"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "スーパームーン", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6307"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "大雨情報", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6308"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "立待月", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a6309"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "全盲", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a630a"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "デング熱", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a630b"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "腕時計型", "__v" : 0 }
{ "_id" : ObjectId("541076c801e48dfe238a630c"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "お月見団子", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a630d"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "ネオナチ", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a630e"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "平均距離", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a630f"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "チュソク", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a6310"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "ウロコ雲", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a6311"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "うろこ雲", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a6312"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "台風14号", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a6313"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "川内原発", "__v" : 0 }
{ "_id" : ObjectId("541076c901e48dfe238a6314"), "xmlurl" : "http://kizasi.jp/rss.xml", "date" : ISODate("2014-09-10T15:50:40Z"), "name" : "初秋", "__v" : 0 }
Type "it" for more
>

node.jsからMongoDBにアクセスしてデータをInsertすることができた

参考

PHP - virtualbox(centos)でmongodbインストールメモ(ついでにrockmongoも) - Qiita http://qiita.com/ryurock/items/3ed551c440cf7b48bbfe