mongoose简介
在说MongoDB数据插入操作之前,我们先来简单了解下它的数据逻辑结构。
MongoDB的逻辑结构是一种层次结构,主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。
文档(document):由键/值对构成,像{a:1};{s:”abc”}等,它是MongoDB核心单元,MongoDB的文档(document),相当于关系数据库中的一行记录。
集合(Collection):多个文档组成一个集合(collection),相当于关系数据库的表。
数据库(database):多个集合(collection),逻辑上组织在一起,就是数据库(database)。
一个MongoDB实例支持多个数据库(database)。
使用mongoose
安装mongoose
1 | npm install mongoose |
引用mongoose
1 | var mongoose = require("mongoose"); |
使用mongoose链接数据库
1 | var db = mongoose("mongodb://user:pass@localhost:port/database"); |
示例:1
2
3
4
5
6
7
8var mongoose = require(“mongoose”);
var db = mongoose.connect(“mongodb://127.0.0.1:27017/test”);
db.connection.on(“error”, function (error) {
console.log(“数据库连接失败:” + error);
});
db.connection.on(“open”, function () {
console.log(“——数据库连接成功!——”);
});
mongodb基础
Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力
Model : 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对
Entity : 由Model创建的实体,他的操作也会影响数据库
Schema —— 一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,也就是说它不具备对数据库的操作能力,仅仅只是数据库模型在程序片段中的一种表现,可以说是数据属性模型(传统意义的表结构),又或着是“集合”的模型骨架。
定义
1 | var mongoose = require("mongoose") |
基本属性类型有:字符串、日期型、数值型、布尔型(Boolean)、null、数组、内嵌文档等
Model —— 由Schema构造生成的模型,除了Schema定义的数据库骨架以外,还具有数据库操作的行为,类似于管理数据库属性、行为的类。
1 | var db = mongoose.connect("mongodb://127.0.0.1:27017/test"); |
数据库中的集合名称,当我们对其添加数据时如果test1已经存在,则会保存到其目录下,如果未存在,则会创建test1集合,然后在保存数据。
Entity —— 由Model创建的实体,使用save方法保存数据,Model和Entity都有能影响数据库的操作,但Model比Entity更具操作性。
1 | var TestEntity = new TestModel({ |
mongoose-mongodb
1、定义模式(Schema)
每个模式映射mongoDB的一个集合(注意映射这个词,下面会讲为什么),它定义(只是定义,不是实现)这个集合里面文档的结构,就是定义这个文档有什么字段,字段类型是什么,字段默认值是什么等。除了定义结构外,还定义文档的实例方法,静态模型方法,复合索引,中间件等。
1 | var mongoose = require('mongoose'); |
{versionKey: false}是干嘛用?如果不加这个设置,我们通过mongoose第一次创建某个集合时,它会给这个集合设定一个versionKey属性值,这个属性值包含这个文档的内部版本,数据库中显示为_v,如图:
通过{versionKey: false}可以配置这个参数,让数据库不再添加这个属性,格式是:new Schema({..}, { versionKey: false });
2、定义模型(Model)
模型用来实现我们定义的模式,调用mongoose.model来编译Schema得到Model。
1 | /*定义模型Student,数据库存的是students*/ |
为什么上面我强调模式的映射,那是因为模式仅仅是和db中集合文档的结构相对应(映射),它并不直接在数据库中操作这个结构,模型才是直接与数据库打交道的存在,可以这么说:模式是定义结构,模型是实现操作。当我们使用mongoose.model(“Student”, Student_Schema)创建Student模型对数据进行操作时,数据库会寻找一个名字叫students集合接受Student模型的操作,特别需要注意的是:1.如果是增加(instance.save)操作时,数据库中没有这个集合,数据库会自动创建这个集合存储数据,这个集合产生规则为:把Model名字字母全部变小写和在后面加复数s。2.如果是删改查三个操作数据库中没有这个集合,那就是没有,删除空修改空返回空。
3、访问模型
1 | var MyStudent = mongoose.model("Student"); |
到这里,已经基本完成了使用mongoose前提操作了。有没有觉得有点繁琐,其实我也觉得挺繁琐,幸运的是234可以一步创建:
1 | var MyStudent = mongoose.model('Student',{ |
4、创建实例(instance)
1 | var sam = new MyStudent({ |
一般只在save(增加)操作中需要。
模型的实例是集合中真实的数据,就是collection中的document,用mysql中的术语来说就是一条记录。模型在数据库中建好了集合和文档结构后,通过实例往里面添加真实的document。
捋一捋模式、模型、实例的关系:模式定义了操作和属性,这些操作和属性包括mongoose自带和自定义,而模型和实例可以对模式里面定义的属性和方法进行引用。模型是mongoose用来和数据库直接打交道的中介,实例是往数据库存的真实数据。模式并非必须,那为什么要分开模式和模型呢?我觉得是遵循了软件设计中“定义和实现分开”这个原则。有的文章说模式没有操作数据库的能力,模型才有,对这个观点,我觉得部分对,虽说模式不能直接操作数据库,但模式定义的方法可以被模型用来操作数据库。官方文档是这么说的:
model.find
Mongoose 模型提供了 find, findOne, 和 findById 方法用于文档查询。
Model.find(query, fields, options, callback)
// fields 和 options 都是可选参数
简单查询
1 | Model.find({ 'csser.com': 5 }, function (err, docs) { // docs 是查询的结果数组 }); |
只查询指定键的结果
1 | Model.find({}, ['first', 'last'], function (err, docs) { |
Model.findOne
与 Model.find 相同,但只返回单个文档
1 | Model.findOne({ age: 5}, function (err, doc){ |
Model.findById
与 findOne 相同,但它接收文档的 _id 作为参数,返回单个文档。_id 可以是字符串或 ObjectId 对象。
1 | Model.findById(obj._id, function (err, doc){ |
Model.count
返回符合条件的文档数
1 | Model.count(conditions,callback) |
Model.remove
删除符合的条件的文档
1 | Model.remove(conditions,callback); |
Model.distinct
查询符合条件的文档并返回根据键分组的结果.
Model.distinct(field,conditions,callback);
Model.where
当查询比较复杂时,用where:
1 | Model |
Model.$where
有时我们需要在 mongodb 中使用 javascript 表达式进行查询,这时可以用 find({$where : javascript}) 方式,$where 是一种快捷方式,并支持链式调用查询。
1 | Model.$where('this.firstname === this.lastname').exec(callback) |
Model.update
使用 update 子句更新符合指定条件的文档,更新数据在发送到数据库服务器之前会改变模型的类型。
1 | var conditions = { name: 'borne' } |
注意:为了向后兼容,所有顶级更新键如果不是原子操作命名的,会统一被按 $set 操作处理,例如:
1 | var query = { name: 'borne' }; |
查询API
如果不提供回调函数,所有这些方法都返回 Query 对象,它们都可以被再次修改(比如增加选项、键等),直到调用exec 方法。
1 | var query = Model.find({}); |
mongodb查询示例
1、db.user.find({});
2、db.user.find();
3、db.user.find({“name”:”user2”});
4、db.user.find({},{“name”:1,”password”:1});
5、db.user.find({},{“_id”:0});
6、查询条件
\$lt,\$lte,\$gt,\$gte,\$ne和<,<=,>,>=,!=是一一对应的,它们可以组合起来以查找一个范围内的值。
db.user.find({“age”:{“\$gte”:”20”,”\$lte”:”30”}});
db.user.find({“age”:{“\$gte”:20,”\$lte”:30}});
7、关联查询
db.user.find({“age”:{“\$in”:[20,25,26]}});
db.user.find({“age”:{“\$nin”:[20,25,26]}});
db.user.find({“age”:{“\$in”:[20,25,26]}});
用$or用于对多个键做or查询。
db.user.find({“\$or”:[{“age”:{“in”:[24,25,26]}},{“name”:”user3”}]});
8、特定类型的查询
null查询
db.user.update({“name”:”user2”},{\$set:{“sex”:null}});
db.user.find({“sex”:{“\$in”:[null]}});
正则表达式
db.user.find({“name”:/^user/});
数组查询
db.food.find({fruit:{\$all:[“apple”,”banana”]}});
db.food.find({“fruit.2”:”peach”});
\$size:查询指定长度的数组
db.food.find({“fruit”:{“\$size”:3}});