以前の投稿で、Mongoose
でMongoDBにアクセスする方法を検証した。本投稿では、本家が公開しているNode.js用の純正ドライバ
の使い方に関するメモになる。
そもそもなぜネイティブドライバを検証したかというと、同一コレクション内に複数のスキーマドキュメントがあり、それぞれのドキュメントにアクセスしようとしたところ、Override error
が出た。どうもMongooseでは、同一コレクションに異なるスキーマを生成することを許可してない
らしい。
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var schema1 = Schema( { name:String } );
var schema2 = Schema( { name:String, age:Number } );
var model1 = mongoose.model('col', schema1);
var model2 = mongoose.model('col', schema2);
model2を取得しようとすると、エラーが発生
する。最初はそんなはずでは?といろいろ調べたが、同じようなことをやろうとしている情報がみつからず、解決に至ってない。
筆者がやろうとしていることは、1つのコレクション内に複数のスキーマをもつドキュメントを詰めたいので、上記のようにモデルが作成できないと、実現できない。なんとなくMongooseは、「NOSQLであるMongoDBをRDBMS
のように使うモジュール」という印象を受けた。それを望んでいるのであれば、Mongooseを使えば良い。
素直にコレクションを分ければ良い話だが、RDBMSの窮屈さがちょっと嫌で、MongoDBのゆるさに期待していたのに、Mongooseにあわせたモデル設計ってのはなんだか違う気がするので、純正のドライバを試してみようと思ったわけである。
基本的MongoDBドライバは、mongoコンソールから実行するコマンドに準拠している。
オンラインヘルプ:http://mongodb.github.io/node-mongodb-native/
ざっくりとだが、基本的なアクセス方法を下記にまとめた。
データの参照(find)
localhostのtestデータベースにアクセスする。コレクションpersons
に対し、name
がtaro
のドキュメントを出力する
var mongo = require('mongodb');
var test = require('assert');
mongo.MongoClient.connect( 'mongodb://localhost/test', function( err, db ){
test.equal(null,err);
var collection = db.collection('persons');
// query
collection.find( {"name":"taro"} ).toArray( function( err, docs ){
docs.forEach( function( doc ){
// output document
console.log( JSON.stringify( doc ) );
});
db.on('close', function() {
console.log( "@db closed.");
});
db.close();
});
});
ページング( sort, limit, skip )
findを実行すると、Cursor
クラスのインスタンスが結果として返される。Cursorクラスのメソッドにsort
やlimit
などのフィルタ関数がある。
下記のようにsort, limit, skipを実行することによって、ページングすることができる。下記の場合、gender
、age
でソートし、一つ目のドキュメントをスキップして、最大2件のドキュメントを返す。
collection.find( {} ).sort( [{"gender":1},{"age":-1}] )
.limit(2).skip(1).toArray( function( err, docs ){
docs.forEach( function( doc ){
// docが2件取得される
});
});
データの追加(insertOne)
nameがryoのドキュメントを追加
する。まとめて複数のドキュメントを追加するinsertMany
という関数もある。
var mongo = require('mongodb');
var test = require('assert');
mongo.MongoClient.connect( 'mongodb://localhost/test', function( err, db ){
test.equal(null,err);
var collection = db.collection('persons');
// insert
collection.insertOne(
{"name":"ryo", "age":34,"children":["aa","bb"],"job":{"name":"ZZZ co.","category":"operator"}},
{}, function(error, result){
console.log(JSON.stringify(result));
db.on('close', function() {
console.log( "@db closed.");
});
db.close();
});
});
データの更新(findOneAndUpdate)
nameがryoのドキュメントを更新
する。
mongoコンソールと同じように$set
,$unset
,$push
,$pushAll
,$pull
,$pullAll
...etcが使える。
var mongo = require('mongodb');
var test = require('assert');
mongo.MongoClient.connect( 'mongodb://localhost/test', function( err, db ){
test.equal(null,err);
var collection = db.collection('persons');
// update
collection.findOneAndUpdate(
{ "name":"ryo"},
{ $set : {"age":43,"job.category":"manager"}, $pushAll :{"children":["666","777"]} },
{}, function(error, result){
console.log(JSON.stringify(result));
db.on('close', function() {
console.log( "@db closed.");
});
db.close();
});
});
データの削除(deleteOne)
nameがryoのドキュメントを削除
する。
var mongo = require('mongodb');
var test = require('assert');
mongo.MongoClient.connect( 'mongodb://localhost/test', function( err, db ){
test.equal(null,err);
var collection = db.collection('persons');
// delete
collection.deleteOne(
{ "name":"ryo" },
{}, function(error, result){
console.log(JSON.stringify(result));
db.on('close', function() {
console.log( "@db closed.");
});
db.close();
});
});
重複を除外したフィールド値を取得(distinct)
genderがmかfのnameを重複除去
して取得する。結果は配列
で取得される。
var mongo = require('mongodb');
var test = require('assert');
mongo.MongoClient.connect( 'mongodb://localhost/test', function( err, db ){
test.equal(null,err);
var collection = db.collection('persons');
// distinct
collection.distinct(
"name",
{ $or : [{ "gender":"m" },{ "gender":"f" }]},
{}, function(error, array){
// ["taro", "ken", "hanako"]
console.log(array);
db.on('close', function() {
console.log( "@db closed.");
});
db.close();
});
});
mongoコンソールの操作とほとんど同じ感覚の操作になる