node.js+MongoDBでtwitter apiを使うときに注意すること

こちらになんの変哲もないjsonがあります.

{"id":255113756093329409,"id_str":"255113756093329409"}

これをJSON.parseすると

{ id: 255113756093329400,  id_str: '255113756093329409' }

お分かりいただけるだろうか?不思議な力によりidの下1桁が9から0になってしまった. このidは先程自分が腹減ったとTwitterでつぶやいたもののstatus idなので最近のつぶやきを扱うには何らかの対策が必要である.

対策1: id_strを使う

Twitter APIは64bit整数が扱えない残念な言語の為にidとつくフィールド全てにid_strというidを文字列にしただけのフィールドを持っている. なのでよっぽどのことがない限りこちらを使えばよい.

対策2: MongoDBのNumberLongを使う

MongoDBではNumberLong('255113756093329409')と書けば64bit整数が扱える. sortしたい,コレクションが大量にあるのでidに20Byteも使うのは勿体無い等の場合こちらを使えばいいだろう.

みんなのアイドルmongooseでNumberLongを使いたい時は,mongoose-longというモジュールがある.

const mongoose = require('mongoose');
require('mongoose-long')(mongoose);
const Schema = mongoose.Schema;
var Status = new Schema({ id: Schema.Types.Long });
mongoose.model('Status', Status);
Status = mongoose.model('Status');
var status = new Status({ id: '255113756093329409' }); // Stringで渡す
console.log(status.id);
console.log(status.id.toString(10));

結果

{ _bsontype: 'Long', low_: 155332609, high_: 59398300 }
255113756093329409

しかしこのmongoose-longは不完全で検索,更新ができなかったりするので,mongooseのlib/schema/number.jsあたりとmongoose-longのlib/index.jsを参考にcastForQuery関数を追加したりする必要がある.