MongoDB的应用

MongoDB是目前最流行的noSQL数据库之一,它是专为Node开发的。

MongoDB的一条记录叫做文档(document),它是一个包含多个字段的数据结构,很类似于JSON格式。

下面是文档的一个例子。

{
"_id" : ObjectId("54c955492b7c8eb21818bd09"),
"address" : {
"street" : "2 Avenue",
"zipcode" : "10075",
"building" : "1480",
"coord" : [ -73.9557413, 40.7720266 ]
},
"borough" : "Manhattan",
"cuisine" : "Italian",
"grades" : [
{
"date" : ISODate("2014-10-01T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2014-01-16T00:00:00Z"),
"grade" : "B",
"score" : 17
}
],
"name" : "Vella",
"restaurant_id" : "41704620"
}

文档储存在集合(collection)之中,类似于关系型数据库的表。在一个集合之中,记录的格式并不需要相同。每个集合之中的每个文档,必须有一个_id字段作为主键。

基本用法

安装完MongoDB数据库以后,使用mongod命令启动MongoDB。

$ mongod

# 或者指定配置文件
$ mongod --config /etc/mongodb.conf

然后,安装Node驱动库。

$ npm install mongodb

脚本里引用MongoDB客户端的代码如下。

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');

var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log('Connected correctly to server.');
db.close();
});

插入数据

var insertDocument = function(db, callback) {
db.collection('restaurants').insertOne( {
"address" : {
"street" : "2 Avenue",
"zipcode" : "10075",
"building" : "1480",
"coord" : [ -73.9557413, 40.7720266 ]
},
"borough" : "Manhattan",
"cuisine" : "Italian",
"grades" : [
{
"date" : new Date("2014-10-01T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : new Date("2014-01-16T00:00:00Z"),
"grade" : "B",
"score" : 17
}
],
"name" : "Vella",
"restaurant_id" : "41704620"
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the restaurants collection.");
callback();
});
};

执行这个操作。

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});

查询操作

取出一个collection里面的所有文档。

var findRestaurants = function(db, callback) {
var cursor =db.collection('restaurants').find( );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc !== null) {
console.dir(doc);
} else {
callback();
}
});
};

执行上面的函数。

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findRestaurants(db, function() {
db.close();
});
});

查询语句的写法如下。

{ <field1>: <value1>, <field2>: <value2>, ... }

下面是一个指定查询条件的例子。

var findRestaurants = function(db, callback) {
var cursor =db.collection('restaurants').find( { "borough": "Manhattan" } );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
console.dir(doc);
} else {
callback();
}
});
};

执行上面的函数。

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findRestaurants(db, function() {
db.close();
});
});

查询的时候,可以指定嵌套属性。

var cursor =db.collection('restaurants').find( { "address.zipcode": "10075" } );

查询条件还可以指定数组的一个值。

var cursor =db.collection('restaurants').find( { "grades.grade": "B" } );

查询条件可以指定运算符。

// 大于
var cursor =db.collection('restaurants').find( { "grades.score": { $gt: 30 } } );

// 小于
var cursor =db.collection('restaurants').find( { "grades.score": { $lt: 10 } } );

查询条件可以指定逻辑运算符。

// AND 运算
var cursor =db.collection('restaurants').find(
{ "cuisine": "Italian", "address.zipcode": "10075" }
);

// OR 运算
var cursor =db.collection('restaurants').find(
{ $or: [ { "cuisine": "Italian" }, { "address.zipcode": "10075" } ] }
);

sort方法用于排序,1代表升序,-1代表降序。

var cursor =db.collection('restaurants').find().sort( { "borough": 1, "address.zipcode": 1 } );

更新数据

更新指定文档。updateOne方法返回更新的文档的数目。

var updateRestaurants = function(db, callback) {
db.collection('restaurants').updateOne(
{ "name" : "Juni" },
{
$set: { "cuisine": "American (New)" },
$currentDate: { "lastModified": true }
}, function(err, results) {
console.log(results);
callback();
});
};

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);

updateRestaurants(db, function() {
db.close();
});
});

更新嵌入的字段。

db.collection('restaurants').updateOne(
{ "restaurant_id" : "41156888" },
{ $set: { "address.street": "East 31st Street" } },
function(err, results) {
console.log(results);
callback();
}
);

更新多个字段。

db.collection('restaurants').updateMany(
{ "address.zipcode": "10016", cuisine: "Other" },
{
$set: { cuisine: "Category To Be Determined" },
$currentDate: { "lastModified": true }
}
,
function(err, results) {
console.log(results);
callback();
});

替换整个文档,除了_id字段。

db.collection('restaurants').replaceOne(
{ "restaurant_id" : "41704620" },
{
"name" : "Vella 2",
"address" : {
"coord" : [ -73.9557413, 40.7720266 ],
"building" : "1480",
"street" : "2 Avenue",
"zipcode" : "10075"
}
},
function(err, results) {
console.log(results);
callback();
});

_id字段不能更新。

删除数据

删除符合条件的所有文档。

var removeRestaurants = function(db, callback) {
db.collection('restaurants').deleteMany(
{ "borough": "Manhattan" },
function(err, results) {
console.log(results);
callback();
}
);
};

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);

removeRestaurants(db, function() {
db.close();
});
});

删除单一文档。

db.collection('restaurants').deleteOne(
{ "borough": "Queens" },
function(err, results) {
console.log(results);
callback();
}
);

删除所有文档。

db.collection('restaurants').deleteMany( {}, function(err, results) {
console.log(results);
callback();
});

删除整个集合。

db.collection('restaurants').drop( function(err, response) {
console.log(response)
callback();
});

聚合操作

var aggregateRestaurants = function(db, callback) {
db.collection('restaurants').aggregate(
[
{ $group: { "_id": "$borough", "count": { $sum: 1 } } }
]).toArray(function(err, result) {
assert.equal(err, null);
console.log(result);
callback(result);
});
};

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
aggregateRestaurants(db, function() {
db.close();
});
});

上面的代码产生下面的结果。

[ { _id: 'Missing', count: 51 },
{ _id: 'Staten Island', count: 969 },
{ _id: 'Manhattan', count: 10259 },
{ _id: 'Brooklyn', count: 6086 },
{ _id: 'Queens', count: 5656 },
{ _id: 'Bronx', count: 2338 } ]

带有过滤条件的聚合。

db.collection('restaurants').aggregate(
[
{ $match: { "borough": "Queens", "cuisine": "Brazilian" } },
{ $group: { "_id": "$address.zipcode" , "count": { $sum: 1 } } }
]).toArray(function(err, result) {
assert.equal(err, null);
console.log(result);
callback(result);
});

索引

生成一个单字段的索引,1表示升序,-1表示降序。

var indexRestaurants = function(db, callback) {
db.collection('restaurants').createIndex(
{ "cuisine": 1 },
null,
function(err, results) {
console.log(results);
callback();
}
);
};

MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
indexRestaurants(db, function() {
db.close();
});
});

生成多个字段的索引。

db.collection('restaurants').createIndex(
{ "cuisine": 1, "address.zipcode": -1 },
null,
function(err, results) {
console.log(results);
callback();
}
);

命令行操作

输入数据。

$ mongoimport --db test --collection restaurants --drop --file primer-dataset.json

Mongoose

多种中间件可以用于连接node.js与MongoDB,目前比较常用的Mongoose。

首先,在项目目录将Mongoose安装为本地模块。


npm install mongoose --save

然后,就可以在node.js脚本中连接MongoDB数据库了。


var mongoose = require('mongoose');

// 连接字符串格式为mongodb://主机/数据库名
mongoose.connect('mongodb://localhost/mydatabase');

注意,运行上面这个脚本时,必须确保MongoDB处于运行中。

数据库连接后,可以对open和error事件指定监听函数。


var db = mongoose.connection;

db.on('error', function callback () {
console.log("Connection error");
});

db.once('open', function callback () {
console.log("Mongo working!");
});

mongoose.Schema方法用来定义数据集的格式(schema),mongoose.model方法将格式分配给指定的数据集。


var Schema = mongoose.Schema;
var userSchema = new Schema({
name : String,
age : Number,
DOB : Date,
isAlive : Boolean
});

var User = mongoose.model('User', userSchema);

var arvind = new User({
name : 'Arvind',
age : 99,
DOB : '01/01/1915',
isAlive : true
});

arvind.save(function (err, data) {
if (err){
console.log(err);
} else {
console.log('Saved : ', data );
}
});
amenzai wechat
扫一扫上面二维码,获取更多内容。
欢迎各位老板打赏