MongoDB
MongoDB
安装&启动
macOS
提示
因为 MongoDB 现在非开源授权,因此已经从homebrew-core
里面移除,你需要通过以下方式安装。
brew services stop mongodb
brew uninstall mongodb
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community
Linux
apt-get install mongodb
service mongodb start
# 查看MongoDB运行状态
mongod
# 创建MongoDB的数据库目录
mkdir -p /data/db
# 访问mongod
mongo
发现有个错误 ERROR: Insufficient free space for journal files 按照这里设置以后我们就能访问mongod
MongoDB 相关工具
- MongoBooster: MongoDB 图形化管理软件,内嵌 MongoShell,ES6 语法,流畅查询及智能感知。
- mongoimport:数据导入工具,JSON,CSV,TSV
- mongoexport:数据导出工具JSON,CSV
- mongodump:二进制导出 (备份)
- bsondump:把导出的二进制文件转为JSON
- mongostat:显示MongoDB 服务器当前状态概览
- BSON:JSON的二进制形式,支持了JSON没有的数据类型
- Mongo DB 驱动: https://docs.mongodb.org/ecosystem/drivers/
- mongorestore:恢复一个二进制导出
使用
下载bookmarks.js,连接本机然后执行 bookmarks.js 导入数据
mongo 127.0.0.1/bookmarks bookmarks.js
连接bookmarks数据库
mongo bookmarks
创建数据库
在MongoDB中,使用use
命令,如果没有这个数据库,那么MongoDB会自动‘创建’
use fullstack
插入
1.只要给JSON格式的文档即可(其中links
是表名),与创建数据库一样,如果没有这个表,则会自动创建
db.links.insert({ title: "BI HELL", url: "http://bihell.com", comment:"great blog", tags:["tutorials", "dev"], saved_on: new Date()});
db.students.insert({"name":"Jose","mark":99})
2.另外一种姿势
var doc = {};
doc.title = "BI HELL";
doc.url = 'http://bihell.com'
doc.tags = ["BI", "SSIS"];
doc.saved_on = new Date
doc.meta ={}
doc.meta.browser = "Internet Expolorer 11"
doc.meta.OS = "Windows 10"
doc
db.links.save(doc)
3.之前查询中的ObjectID("_id" : ObjectId("55f82dbfbe4d5bc5bdb1c366")) 是MongoDB默认生成的. 我们可以在插入的时候指定
db.links.insert({ _id:3, name: "test"});
查询
1.返回所有数据
db.links.find()
// 格式化显示返回的结果
db.posts.find().pretty()
2.返回查询结果的第一条记录
db.links.find()[0]
3.返回第一条记录的id
db.links.find()[0]._id
4.显示集合当前的条数
db.links.count()
5.获得记录的创建时间 (系统生成的ObjectID才有效)
db.links.find()[3]._id.getTimestamp()
当然也可以自己生成一个ObjectId
new ObjectId
6.使用findOne,只返回一条记录
db.links.findOne({favorites:100});
7.使用findOne 只显示email='johndoe@gmail.com' 的name
db.users.findOne({ email: 'johndoe@gmail.com'}).name
8.设置需要显示的字段,例子中是title 和 url, 其中1和ture等价
db.links.find({favorites:100},{title:1, url: true});
9.不显示tags字段
db.links.find({favorites:100},{ tags: 0 }).forEach(printjson);
10.查询子对象
db.users.findOne({ 'name.first':'John'});
11.只显示name子对象中的last
db.users.findOne({ 'name.first':'John'},{'name.last': 1});
12.结果直接显示成Json样式
db.users.find().forEach(printjson)
13.查找email为'johndoe@gmail.com’的记录
db.users.find({ email: 'johndoe@gmail.com'});
db.users.find({ passwordHash: 'another_password_hash' }).forEach(printjson);
14.组合查询
根据上文学习的内容进行简单的综合查询
db.users.insert({ name: "Andrew"})
var a =db.users.findOne({ name: "Andrew"});
a
a._id
db.links.insert({ title: "BIHell", url:"http://bihell.com",userId: a._id})
db.links.find()
// 查询结果返回第四条记录
var link = db.links.find()[3]
link
db.users.findOne({ _id: link.userId});
15.使用函数
var f = function(){ return this.name.first === "John"};
db.users.find(f);
db.users.find({$where: f});
16.去重
db.links.distinct('favorites');
17.分组聚合 关于分组具体的解说可以看这里
> db.links.group({
... key: { userId: true},
... initial: {favCount:0},
... reduce: function (doc,o) { o.favCount += doc.favorites},
... finalize: function (o) { o.name = db.users.findOne({ _id: o.userId}).name ; } } );
18.正则
db.links.find({ title: /tuts+$/});
db.links.find({ title: /tuts+$/},{title: 1 } );
db.links.find({ title: { $regex: /tuts+$/}},{title: 1 } );
db.links.find({ title: { $regex: /tuts+$/, $ne: "Mobiletuts+"}},{title: 1 } );
19.计数
db.users.find({'name.first': 'John'}).count();
db.users.count({ 'name.first': 'John'});
db.users.count();
20.排序 sort里面 1为正序 -1为反序
db.links.find({},{title:1, _id:0}).sort({title:1});
db.links.find({},{title:1,favorites :1 ,_id:0}).sort({ favorites : -1,title:1});
21.限定返回记录的数量
db.links.find({},{title:1, favourites:1,_id:0}).sort({ favorites : -1 }).limit(1);
db.links.find().limit(2).forEach(printjson);
22.分页
db.links.find({},{title:1, _id:0}).skip(03).limit(3);
db.links.find({},{title:1, _id:0}).skip(13).limit(3);
db.links.find({},{title:1, _id:0}).skip(2*3).limit(3);
操作符
1.大于 $gt
例如找到favorites 大于50的记录并且只返回title 和favorites 列
db.links.find({ favorites: { $gt:50}},{title:1, favorites:1,_id:0});
2.小于 $lt
db.links.find({ favorites: { $lt:150}},{title:1, favorites:1,_id:0});
3.小于等于$lte
db.links.find({ favorites: { $lte:150}},{title:1, favorites:1,_id:0});
4.大于等于$gte
db.links.find({ favorites: { $gte:150}},{title:1, favorites:1,_id:0});
5.大于100小于300
db.links.find({ favorites: { $gt:100, $lt:300}},{title:1, favorites:1,_id:0});
6.$ne 不等于
db.links.find({ tags: { $ne: 'code'}},{ title:1,tags:1});
7.in
db.users.find({'name.first':{$in:['John','Jane']}},{'name.first':1});
db.links.find({ tags: { $in: ['marketplace','code']}},{ title: 1,tags:1,_id:0})
8.not in
db.users.find({'name.first':{$nin:['John','Jane']}},{'name.first':1});
9.$all 匹配所有结果
db.links.find({ tags: {$all:['marketplace','code']}},{title:1,tags:1,_id:0})
10.or
db.users.find({ $or:[{'name.first':"John"},{'name.last':"Wilson"}]},{name:1});
11.not or
找到'name.first'不为John 或者 'name.last' 不为 Wilson的记录
db.users.find({$nor:[{'name.first':"John"},{'name.last':"Wilson"}]},{name:1});
12.and
db.users.insert({name:{first:"John",last:"Jones"}});
db.users.find({$and: [{'name.first':"John"},{"name.last":"Jones"}]});
13.exist
db.users.find({email:{$exists:true}},{name:1,_id:0});
14.not exist
db.users.find({email:{$exists:false}},{name:1,_id:0});
15.取余 mod, 查找favorites 除5余0的记录
db.links.find({favorites:{$mod:[5,0]}},{title:1,favorites:1,_id:0})
16.找到favorites除5不余0的记录
db.links.find({favorites:{$not: {$mod:[5,0]}}},{title:1,favorites:1,_id:0})
17.查找logins字段里面 minutes=20的记录
db.users.find({logins: {$elemMatch: { minutes:20}}});
18.查找logins字段中 at<2012-03-30的记录,(注意日期与MongoDB日期有差异的)
db.users.find({logins: {$elemMatch: { at: { $lt: new Date(2012,03,14)}}}}).forEach(printjson);
19.使用$where (即使用js ,尽量少用,效率低)
db.users.find({$where:'this.name.first==="John"'})
db.users.find({$where:'this.name.first==="John"',age:30})
20.如果只是用where ,你可以省略掉 $where
db.users.find('this.name.first==="John"')
更新
1.更新第一条记录
找到name.first=John的记录,然后把job的值更新为developer
db.users.update({'name.first':'John'},{job:'developer'});
2.更新所有记录
第四个参数设为ture就可以更新所有记录
db.users.update({'name.first':'Jane'},{$set:{job:"developer"}},false,true);
3.更新或插入
第三个参数设为ture的时候,如果找不到第一个参数的匹配记录,则直接插入参数2作为新纪录
db.users.update({ name: "Kate Wills"},{ name:"Kate Wills",job:"LISP Developer"},true);
db.users.find({ name:"Kate Wills"});
4.更新某值
var n = {title:"Nettuts+"};
db.links.find(n , {title: 1, favorites :1});
db.links.update(n,{$inc: { favorites :5}}); --原值加5
db.links.find(n , {title: 1, favorites :1});
5.SET 如果原先有字段则更新,没有则直接插入一个字段
> var q = { name: "Kate Wills" };
> db.users.find(q);
{ "_id" : ObjectId("5602bcd248c642324487d01f"), "name" : "Kate Wills", "job" : "LISP Developer" }
> db.users.update(q,{$set: {job:'Web Developer'}});
> db.users.find(q);
{ "_id" : ObjectId("5602bcd248c642324487d01f"), "job" : "Web Developer", "name" : "Kate Wills" }
> db.users.update(q,{$set:{email: 'katewills@gmail.com'}});
> db.users.find(q);
{ "_id" : ObjectId("5602bcd248c642324487d01f"), "email" : "katewills@gmail.com", "job" : "Web Developer", "name" : "Kate Wills" }
6.UNSET 去掉某个字段
> db.users.update(q,{$unset:{job:"Web Developer"}});
> db.users.find(q);
{ "_id" : ObjectId("5602bcd248c642324487d01f"), "email" : "katewills@gmail.com", "name" : "Kate Wills" }
7.findAndModify 其中 new设为true 返回更改后的值,设为false则返回更改前的值
> db.users.findAndModify({
... query:{name:"Kate Wills"},
... update:{$set:{age:20}},
... new:true});
{
"_id" : ObjectId("5602bcd248c642324487d01f"),
"age" : 20,
"email" : "katewills@gmail.com",
"name" : "Kate Wills"
}
8.$push增加item
db.links.update(n,{$push:{ tags: ‘blog’}});
9.$pushAll 增加多个item
db.links.update(n,{ $pushAll : { tags: [‘one’,’two’]}});
与上面不同,这会下面这个会增加子项
db.links.update(n,{$push : { tags:[‘one’ ,’two’] }});
10.$addToSet 如果增加的item已经存在,则不添加
db.links.update(n,{$addToSet:{tags:’code’}});
db.links.update(n,{$addToSet: {tags: {$each: [‘one’,’four’]}}});
11.$pull 移除item
db.links.update(n,{$pull: {tags:’four’}});
12.移除多个item
db.links.update(n,{$pullAll: {tags:[‘two’,’three’]}});
db.links.update(n,{$pull:{tags:[‘one’,’two’]}});
13.移除第一个item或者最后一个item
db.links.update(n,{$pop:{tags:-1}});
14.查找数组型子项需要用到$ 位置符
db.users.update({'logins.minutes': 10},{$inc:{'logins.$.minutes':1}})
db.users.update({'logins.minutes': 20},{$inc:{'logins.$.minutes':1}},false,true)
db.users.update({'logins.minutes': 20},{$set:{random:true }},false,true)
db.users.update({'logins.minutes': 20},{$set:{'logins.$.location':'unknown' }},false,true)
15.重命名字段
db.users.update({random:true},{$rename:{'random':'something_else'}},false,true);
删除
1.删除users表
db.users.remove()
2.删除name.first = John的记录
db.users.remove({ 'name.first':"Bob"})
3.删掉记录并返回
> db.users.findAndModify({
... query:{'name.first':/B/},
... remove:true});
4.删除一个collections
> db.other.insert({name:"Andrew"});
> show collections
> db.other.drop();
5.删除数据库
> use other
> db.test.insert({});
> show dbs
> db
> db.dropDatabase()
> db --此时还能看到other数据库,不过实际上已经删除了,这个只是内存中的
> show dbs
索引
注意
MongoDB一个查询只能使用一个索引
1.显示查询计划
db.links.find({title:'Nettuts+' }).explain();
2.id列默认做了索引
db.links.find({"_id" : ObjectId("55f983616ffe01d4461ef22b")}).explain();
3.创建一个索引
db.links.ensureIndex({title:1});
4.查找索引
db.system.indexes.find()
5.一些建立索引的参数
- dropDups 表示如果有重复值,只记录第一条
db.links.ensureIndex({title:1},{unique:true, dropDups:true});
- sparse 如果文档中没有title字段则不包含在索引中
db.links.ensureIndex({title:1},{unique:true, dropDups:true});
db.links.ensureIndex({title:1},{sparse:true});
6.组合索引
db.links.ensureIndex({title:1,url:1});
7.删除索引
db.system.indexes.find()
db.links.dropIndex("title_1")
还原
mongorestore -d bihell ~/Downloads/elm