mongooseはスキーマで宣言されていないkey:valueは保存してくれない。MongoDBっぽくないけど安全ではある。
でも、webhookで色々なjsonがサーバープッシュされてくるAPIのデータを全部保存したい場合に困る。例えばtwitterやjawbone upのstream APIとかを、mongooseでスキーマレスになんでも保存したい。


方法1 Mixedを使う


調べると、Schema.Types.Mixedを使えとか書いてある。

var Any = new Schema({ any: Schema.Types.Mixed });
ただこの方法だと、なんでも保存できるanyの中に保存しろって事なんだけど、documentの中の深い部分を検索する事になってめんどい。


方法2 mongo driverを直接使う


mongoose.connections配列がnode-mongodb-nativeなので、ここに直接insertすればschema無いデータも保存できる。

例として、jawbone-up24がwebhookでプッシュしてくるjsonを全部eventsというcollectionに保存する。


model定義

## 空のschemaを作る
eventSchema = new mongoose.Schema

## 直接insert
eventSchema.statics.insert_webhook = (data, callback = ->) ->
mongoose.connections[0].collection('events').insert data, callback

mongoose.model 'Event', eventSchema
スキーマ関係なく直接保存するメソッドをmongooseのmodelに生やした。
mongooseのmodel Eventにスキーマ登録すると、mongoでは複数形のevents collectionになる


expressでwebhook受信してmongo driverに直接保存

Event = mongoose.model 'Event'
app.use bodyParser.json()

app.post '/webhook', (req, res) ->

## jawboneはevents[0]にデータが入ってるので、それを保存する
Event.insert_webhook req.body.events[0], (err, res) ->
console.log "保存した" unless err

return res.end "ok"


この方法だとcontroller側から使う部分もmongooseっぽいし、query投げるのもmongoose風に普通に書ける

eventSchema.statics.last_move_of_user = (user_id, callback) ->
@find
user_xid: user_id
type: 'move'
.sort
timestamp: 'desc'
.limit 1
.exec callback