mongooseで任意のデータを保存（再掲）

（Qiitaのアカウント作成しなおしたので再掲）

mongooseで任意のデータを保存する方法として[こんなやり方](http://shokai.org/blog/archives/9187)があるらしい。写経がてら自分なりにコードを書いてみた。

```js:anydata.js
'use strict';
var mongoose = require('mongoose'),
    async = require('async');           // テストコード用

var anyDataSchema = new mongoose.Schema({
// 空のスキーマを定義
});
anyDataSchema.static('insert', function (data, callback) {
        this.collection.insert(data, callback);
});
anyDataSchema.static('drop', function (callback) {
        this.collection.drop(callback);
});
mongoose.model('anyData', anyDataSchema);
var anyData = mongoose.model('anyData');

// 使ってみる
async.series([
        function (next) {
                // データベースに接続して、テストデータを削除
                mongoose.connect('mongodb://localhost/schemaless-test');
                anyData.drop();
                next(null, '1');
        },
        function (next) {
                // テストデータを保存
                var testdata = [ {
                        name: "name1",
                        score: 80
                }, {
                        name: "name2",
                        score: 60,
                        age: 18
                }, {
                        name: "name3",
                        score: 90
                } ];
                anyData.insert(testdata, function (err, data) {
                        err || console.log('inserted:', data);
                        next(null, '2');
                });
        },
        function (next) {
                // いくつかの方法でデータを検索してみる
                async.parallel([
                        // 全部のデータを表示
                        function (next) {
                                anyData
                                .find({}, { "_id": 0 })
                                .exec(function (err, data) {
                                        err || console.log('all data:', data);
                                        next(null, '3-1');
                                });
                        },
                        // 80点より高得点の人を表示
                        function (callback) {
                                anyData
                                .find({}, { "_id": 0 })
                                .where('score').gt(80)
                                .exec(function (err, data) {
                                        err || console.log(
                                                'where score gt 80:', data);
                                        next(null, '3-2');
                                });
                        },
                        // 16才より高年齢の人を表示
                        function (callback) {
                                anyData
                                .find({}, { "_id": 0 })
                                .where('age').gt(16)
                                .exec(function (err, data) {
                                        err || console.log(
                                                'where age gt 16:', data);
                                        next(null, '3-3');
                                });
                        }
                ],
                function (err, results) {
                        next(null, '3');
                });
        },
        function (next) {
                mongoose.disconnect();
                next(null, '4');
        }
]);
```

結果はこんな感じになりました。

```
inserted: [ { name: 'name1', score: 80, _id: 547ae136bd7bec2b360cd35f },
  { name: 'name2',
    score: 60,
    age: 18,
    _id: 547ae136bd7bec2b360cd360 },
  { name: 'name3', score: 90, _id: 547ae136bd7bec2b360cd361 } ]
all data: [ { name: 'name1', score: 80 },
  { name: 'name2', score: 60, age: 18 },
  { name: 'name3', score: 90 } ]
where score gt 80: [ { name: 'name3', score: 90 } ]
where age gt 16: [ { name: 'name2', score: 60, age: 18 } ]
```

ポイントは、次の定義でmongoDB driverのinsertを使えるようにしているだけ。

```js
anyDataSchema.static('insert', function (data, callback) {
        this.collection.insert(data, callback);
});
```

スキーマ定義は使わないので空にしていますが、普通にスキーマ定義しておけば、

```js
var anyDataSchema = new mongoose.Schema({
        name: String,
        score: Number
});
    :
var testdata = new anyData();
testdata.name = "name4";
testdata.score = 30;
testdata.save();
```

みたいなこともできます。