コードを舐める日々

わからないことがわからないことをしる日々

mongodb で auto increment の運用をするにはどうすればいいか

mongodb は すべてのテーブルに _id という 識別子 が必ず含まれている。

insert した時に、自動的に一意性キーとして ObjectId("514af36644f9cb2eb8000002") といったような感じで生成される。

それを ObjectId ではなくて、数字による auto increment として自動生成させるにはどうすればいいかという話。

mongodb 公式サイトに 方法が書かれていたので、参考に書く。

http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

まずログインし、 test データベースに接続。

 # mongo
 use test

auto increment の元である、counters テーブルを作成。

 db.counters.insert(
     {
        _id: "entry",
        seq: 0
     }
 )

counters テーブルにある _id を参照して +1 にして返すといった getNextSequence 関数を作成。

 function getNextSequence(name) {
    var ret = db.counters.findAndModify(
           {
             query: { _id: name },
             update: { $inc: { seq: 1 } },
             new: true
           }
    );
    return ret.seq;
 }

実際に id が auto increment になっているか、 entry テーブルを作成し検証してみる。 id に etNextSequence("entry") と書いているところに注目。

 db.entry.insert(
    {
      _id: getNextSequence("entry"),
      title: "express-local をつかってログイン機能を実装してみる",
      body: "express-local で自前サービスのログイン機能…",
      created: new Date(),
      updated: new Date()
    }
 )
 db.entry.insert(
    {
      _id: getNextSequence("entry"),
      title: "mongodb をつかってみたよ",
      body: "SQL や NoSQL のいいところを取ったといわれている…",
      created: new Date(),
      updated: new Date()
    }
 )

そして、 _id がどうなっているか entry テーブルの中身をみてみよう。

> db.entry.find()
{ "_id" : 1, "title" : "express-local をつかってログイン機能を実装してみる", "body" : "express-local で自前サービスのログイン機能…", "created" : ISODate("2013-03-23T05:07:06.568Z"), "updated" : ISODate("2013-03-23T05:07:06.568Z") }
{ "_id" : 2, "title" : "mongodb をつかってみたよ", "body" : "SQL や NoSQL のいいところを取ったといわれている…", "created" : ISODate("2013-03-23T05:07:25.824Z"), "updated" : ISODate("2013-03-23T05:07:25.824Z") }

利用場面はいくつかあるけれど、ひとつの例としては、個別記事テーブルのIDをつける時。 最近 cookpad のレシピや nanapi のレシピをみてみると、ページID が数字になっている。

きのことトマトの卵スープ by rose12 [クックパッド] 簡単おいしいみんなのレシピが142万品

http://cookpad.com/recipe/1896272

とか、

意外と知らない?iPhoneのアプリを完全に終了させる方法 | nanapi [ナナピ]

http://nanapi.jp/60249/

mongodb を使って作るとしたら、という場面に使える。