7月072014
0
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を作るスキーマ関係なく直接保存するメソッドをmongooseのmodelに生やした。
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 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