一、数据库基础命令
1、关于database的基础命令
- 查看所有的数据库:show dbs / show databases
- 切换数据库:use db_name
- 查看当前的数据库:db
- 删除当前的数据库: db.dropDatabase()
2、关于集合的基础命令
- 不手动创建集合:向不存在的集合中第一次加入数据时,集合会被创建出来
- 手动创建集合:db.createCollection(name,option)
db.createCollection("stu")
db.createCollection("stu",{capped:true, size:10})
参数capped:默认值为false表示不设置上限,值为true表示设置上限;
参数size:当capped值为true时,需要指定此参数,表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节
- 查看集合:show collections
> use test
> show collections
products
stu
t250
- 删除集合:db.集合名称.drop()
> db.t250.drop()
true
3、数据类型
3.1、类型
- Object ID:文档ID (文档:从数据库里取出来的一个一个字典)
- String:字符串,最常用,必须是有效的UTF-8
- Boolean:存储一个布尔值,true或false
- Integer:整数可以是32位或64位,这取决于服务器
- Double:存储浮点值
- Arrays:数组或列表,多个值存储到一个键
- Object:用于嵌入式的文档,即一个值为一个文档
- Null:存储Null值
- Timestamp:时间戳,表示从1970-1-1到现在的总秒数
- Date:存储当前日期或时间的UNIX时间格式
3.2、注意点
- 创建日期语句如下 :参数的格式为YYYY-MM-DD
> new Date("2018-01-15")
ISODate("2018-01-15T00:00:00Z")
In [1]:import datetime
In [2]:datetime.datetime.now()
Out[2]:datetime.datetime(2018, 1, 15, 16, 1, 20, 95321)
- 每个文档都有一个属性,为_id,保证每个文档的唯一性
- 可以自己去设置_id插入文档,如果没有提供,那么MongoDB为每个文档提供了一个独特的_id,类型为objectID
- objectID是一个12字节的十六进制数:
前4个字节为当前时间戳
接下来3个字节的机器ID
接下来的2个字节中MongoDB的服务进程id
最后3个字节是简单的增量值
> db
test
> db.test1000.insert({"name" : "xiaowang", "age" : 10})
WriteResult({"nInserted" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaowang", "age" : 10 }
> db.test1000.insert({name : "xiaohong", age : 18})
WriteResult({"nInserted" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaowang", "age" : 10 }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
二、数据库的增删改
1、插入
- db.集合名称.insert(document)
db.stu.insert({name:'gj', gender:1})
db.stu.insert({_id:"20170101", name:'gj', gender:1})
- 插入文档时,如果不指定_id参数,MongoDB会为文档分配一个唯一的ObjectId
2、保存
- db.集合名称.save(document)
> db.test1000.insert({_id:10010, name:"xiaogang", age:30})
WriteResult({"nInserted" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaowang", "age" : 10 }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 30 }
> db.test1000.insert({_id:10010, name:"xiaogang", age:40})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.test1000 index:_id_ dup key
}
})
> db.test1000.save({_id:10010, name:"xiaogang", age:40})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaowang", "age" : 10 }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
mongodb插入数据
- db.collecion.insert({}) :插入数据, _id 存在就报错
- db.collection.save({}):插入数据, _id 存在会更新
3、简单查询
- db.集合名称.find()
4、更新
- db.集合名称.update(<query>, <update>, {multi: <boolean>})
参数query:查询条件
参数update:更新操作符
参数multi:可选,默认是false,表示只更新找到的第一条记录,值为true表示把满足条件的文档全部更新
db.stu.update({name : 'hr'}, {name : 'mnc'}) //更新一条
db.stu.update({name : 'hr'}, {$set : {name : 'hys'}}) //更新一条
db.stu.update({} , {$set : {gender : 0}}, {multi : true}) //更新全部
- 注意:" multi update only works with $ operators "
> db.test1000.update({name : 'xiaowang'}, {name : 'xiaozhao'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
> db.test1000.update({name : 'xiaowang'}, {$set : {name : 'xiaozhang'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaozhang", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
> db.test1000.insert({"name" : "xiaozhang", "age" : 40 })
WriteResult({"nInserted" : 1})
> db.test1000.insert({"name" : "xiaozhang", "age" : 22 })
WriteResult({"nInserted" : 1})
> db.test1000.insert({"name" : "xiaozhang", "age" : 18 })
WriteResult({"nInserted" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaozhang", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
{"_id" : ObjectId("5a5c6341018046c04d86533b"), "name" : "xiaozhang", "age" : 40 }
{"_id" : ObjectId("5a5c6344018046c04d86533c"), "name" : "xiaozhang", "age" : 22 }
{"_id" : ObjectId("5a5c6347018046c04d86533d"), "name" : "xiaozhang", "age" : 18 }
> db.test1000.update({name : 'xiaozhang'}, {$set : {name : 'xiaohong'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
{"_id" : ObjectId("5a5c6341018046c04d86533b"), "name" : "xiaozhang", "age" : 40 }
{"_id" : ObjectId("5a5c6344018046c04d86533c"), "name" : "xiaozhang", "age" : 22 }
{"_id" : ObjectId("5a5c6347018046c04d86533d"), "name" : "xiaozhang", "age" : 18 }
> db.test1000.update({name : "xiaozhang"}, {$set : {name : "xiaohong"}},
{multi : true}})
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3})
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : ObjectId("5a5c60e2018046c04d86533a"), "name" : "xiaohong", "age" : 18 }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
{"_id" : ObjectId("5a5c6341018046c04d86533b"), "name" : "xiaohong", "age" : 40 }
{"_id" : ObjectId("5a5c6344018046c04d86533c"), "name" : "xiaohong", "age" : 22 }
{"_id" : ObjectId("5a5c6347018046c04d86533d"), "name" : "xiaohong", "age" : 18 }
- db.test1000.update({name : "xiaowang"}, {name : "xiaozhao"})
把name为xiaowang的数据替换为 {name : "xiaozhao"}
- db.test1000.update({name : "xiaohong"}, {$set : {name : "xiaozhang"}})
把name为xiaowang的数据中的name的值更新为xiaozhang
- db.test1000.update({name : "xiaozhang"}, {$set : {name : "xiaohong"}}, {multi : true})
{multi : true} 达到更新多条的目的
5、删除
- db.集合名称.remove(<query>, {justOne: <boolean>})
参数query:可选,删除的文档的条件
参数justOne:可选,如果设为true或1,则只删除一条,默认false,表示删除多条
> db.test1000.remove({name : 'xiaohong'}, {justOne: true})
WriteResult({ "nRemoved" : 1 })
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
{"_id" : ObjectId("5a5c6341018046c04d86533b"), "name" : "xiaohong", "age" : 40 }
{"_id" : ObjectId("5a5c6344018046c04d86533c"), "name" : "xiaohong", "age" : 22 }
{"_id" : ObjectId("5a5c6347018046c04d86533d"), "name" : "xiaohong", "age" : 18 }
> db.test1000.remove({name : 'xiaohong'})
WriteResult({ "nRemoved" : 3 })
> db.test1000.find()
{"_id" : ObjectId("5a5c6090018046c04d865339"), "name" : "xiaozhao" }
{"_id" : 10010, "name" : "xiaogang", "age" : 40 }
三、数据高级查询
1、数据查询
- 方法find(): 查询
db.集合名称.find({条件文档})
- 方法findOne():查询,只返回第一个
db.集合名称.findOne({条件文档})
- 方法pretty(): 将结果格式化
db.集合名称.find({条件文档}).pretty()
> db.stu.find()
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.find({age : 20})
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
> db.stu.find({age : 18})
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.findOne({age : 18})
{
"_id" : ObjectId("5a0401d5507a7101e4eaa601"),
"name" : "黄蓉",
"hometown" : "桃花岛",
"age" : 18,
"gender" : false
}
> db.stu.find({age : 18}).pretty()
{
"_id" : ObjectId("5a0401d5507a7101e4eaa601"),
"name" : "黄蓉",
"hometown" : "桃花岛",
"age" : 18,
"gender" : false
}
{
"_id" : ObjectId("5a0401d5507a7101e4eaa601"),
"name" : "华筝",
"hometown" : "蒙古",
"age" : 18,
"gender" : false
}
{
"_id" : ObjectId("5a0401d5507a7101e4eaa601"),
"name" : "洪七公",
"hometown" : "华山",
"age" : 18,
"gender" : true
}
2、比较运算符
- 等于: 默认是等于判断, 没有运算符
- 小于:$lt (less than)
- 小于等于:$lte (less than equal)
- 大于:$gt (greater than)
- 大于等于:$gte
- 不等于:$ne
> db.stu.find({age : {$lte : 18}})
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.find({age : {$lt : 18}})
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
3、范围运算符
- 使用"$in", "$nin" 判断是否在某个范围内
db.stu.find({age : {$in : [18, 28]}}) // 查询年龄为18、28的学生
4、逻辑运算符
- and:在json中写多个条件即可
// 查询年龄大于或等于18,并且性别为true的学生
db.stu.find({age : {$gte : 18}, gender : true})
- or: 使用"$or",值为数组,数组中每个元素为json
// 查询年龄大于18,或性别为false的学生
db.stu.find({$or : [{age : {$gt : 18}}, {gender : false}]})
db.stu.find({$or : [{age : {$gte : 18}}, {gender : true}], name : 'gj'}) //
5、支持正则表达式
- 使用"//"或"$regex"编写正则表达式
db.stu.find({name : /^⻩/}) // 查询姓黄的学生
db.stu.find({name : {$regex:'^⻩'}}) // 查询姓黄的学生
> db.products.find()
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
{ "_id" : 104, "sku" : "abc123", "description" : "Single line description." }
> db.products.find({sku : /^abd/})
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 104, "sku" : "abc123", "description" : "Single line description." }
> db.products.find({sku : {$regex : "789$"}})
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
6、limit和skip
- ⽅法limit():⽤于读取指定数量的⽂档
db.集合名称.find().limit(NUMBER)
db.stu.find().limit(2) // 查询2条学⽣信息
- ⽅法skip():⽤于跳过指定数量的⽂档
db.集合名称.find().skip(NUMBER)
db.stu.find().skip(2)
> db.products.find().limit(2)
{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
> db.products.find().skip(2)
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
{ "_id" : 104, "sku" : "abc123", "description" : "Single line description." }
> db.products.find().skip(2).limit(2)
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
7、自定义查询
- 使用"$where"后⾯写⼀个函数,返回满足条件的数据
db.stu.find({
$where:function() {
return this.age > 30;}
}) // 查询年龄大于30的学⽣
> db.stu.find({$where : function(){return this.age <= 18}})
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.find({age : {$lt : 18}})
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
8、投影
- 在查询到的返回结果中,只选择必要的字段
db.集合名称.find({},{字段名称:1,...})
参数为字段与值,值为1表示显示
特殊: 对于_id列默认是显示的,如果不显示需要明确设置为0
> db.stu.find({age : {$gt : 18}}, {name : 1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖" }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师" }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷" }
> db.stu.find({age : {$gt : 18}}, {name : 1, hometown : 1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖",
"hometown" : "蒙古" }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师",
"hometown" : "桃花岛" }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷",
"hometown" : "大理" }
> db.stu.find({age : {$gt : 18}}, {name : 1, _id : 0})
{"name" : "郭靖" }
{"name" : "黄药师" }
{"name" : "段王爷" }
9、排序
- 方法sort(),用于对集合进行排序
db.集合名称.find().sort({字段:1,...})
参数1为升序排列
参数-1为降序排列
> db.stu.find()
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.find.sort({age : 1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
> db.stu.find.sort({age : -1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理", "age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
> db.stu.find.sort({age : -1, gender : -1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
> db.stu.find({age : {$gt : 18}}).sort({age : 1})
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
10、统计个数
- 方法count()⽤于统计结果集中文档条数
> db.stu.find.count()
7
> db.stu.find({age : {$gt : 18}}).count()
3
> db.stu.find({age : {$gte : 18}}).count()
6
> db.stu.count()
7
> db.stu.count({age : {$lte : 18}})
4
11、消除重复
- 方法distinct()对数据进行去重
> db.stu.distinct("hometown")
["蒙古", "桃花岛", "大理", "华山"]
> db.stu.distinct("age")
[20, 18, 40, 16, 45]
> db.stu.distinct("hometown", {age : {$gt : 20}})
["桃花岛", "大理"]
四、数据的备份和恢复
1、备份
- 语法
mongodump -h dbhost -d dbname -o dbdirectory
-h: 服务器地址, 也可以指定端口号
-d: 需要备份的数据库名称
-o: 备份的数据存放位置, 此目录中存放着备份出来的数据
mongodump -h 192.168.196.128:27017 -d test1 -o ~/Desktop/test1bak
2、恢复
- 语法
mongorestore -h dbhost -d dbname --dir dbdirectory
-h: 服务器地址
-d: 需要恢复的数据库实例
--dir: 备份数据所在位置
mongorestore -h 192.168.196.128:27017 -d test2 --dir ~/Desktop/test1bak/test1
五、聚合和管道
1、聚合aggregate
- 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
db.集合名称.aggregate({管道 : {表达式}})
2、常用管道
在mongodb中,文档处理完毕后,通过管道进行下一次处理
常用管道如下:
$group: 将集合中的文档分组,可用于统计结果
$match: 过滤数据,只输出符合条件的文档
$project: 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
$sort: 将输⼊文档排序后输出
$limit: 限制聚合管道返回的文档数
$skip: 跳过指定数量的文档, 并返回余下的文档
$unwind: 将数组类型的字段进行拆分
3、表达式
处理输入文档并输出
- 语法:表达式: '$列名'
常用表达式:
$sum: 计算总和,$sum:1 表示以一倍计数
$avg: 计算平均值
$min: 获取最小值
$max: 获取最大值
$push: 在结果文档中插⼊值到一个数组中
$first: 根据资源文档的排序获取第一个文档数据
$last: 根据资源文档的排序获取最后一个文档数据
4、聚合之group
- $group
> db.stu.find()
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.aggregate(
{$group : {_id : "$gender"}}
)
{"_id" : false}
{"_id" : true}
> db.stu.aggregate(
{$group : {_id : "$gender", count : {$sum : 1}}}
)
{ "_id" : false, "count" : 2}
{ "_id" : true, "count" : 5}
> db.stu.aggregate(
{$group : {_id : "$gender", count : {$sum : 1}, avg_age : {$avg : "$age"}}}
)
{ "_id" : false, "count" : 2, "avg_age" : 18}
{ "_id" : true, "count" : 5, "avg_age" : 27.8}
> db.stu.aggregate(
{$group : {_id : "$hometown", mean_age : {$avg : "$age"}}}
)
{ "_id" : "华山", "mean_age" : 18}
{ "_id" : "大理", "mean_age" : 30.5}
{ "_id" : "桃花岛", "mean_age" : 29}
{ "_id" : "蒙古", "mean_age" : 19}
- Group by null
将集合中所有文档分为一组
> db.stu.aggragate(
{$group : {_id : null, count : {$sum : 1}, mean_age : {$avg : "$age"}}}
)
{ "_ic" : null, "count" : 7, "mean_age" : 25}
- $group的注意点
$group 对应的字典中有几个键,结果中就有几个键
分组依据需要放到 _id 后面
取不同的字段的值需要使用$, $gender , $age
取字典嵌套的字典中的值的时候 $_id.country
能同时按照多个键进行分组 {$group:{_id:{country:"$country",province:"$province"}}}
结果是: {_id:{country:"",province:""}
- 透视数据
- 练习
> db.tv3.find()
{ "_id" : ObjectId("5a07ff40699a3774b04612c1"), "country" : "china",
"province" : "sh", "userid" : "a" }
{ "_id" : ObjectId("5a07ff40699a3774b04612c2"), "country" : "china",
"province" : "sh", "userid" : "b" }
{ "_id" : ObjectId("5a07ff40699a3774b04612c3"), "country" : "china",
"province" : "sh", "userid" : "a" }
{ "_id" : ObjectId("5a07ff40699a3774b04612c4"), "country" : "china",
"province" : "sh", "userid" : "c" }
{ "_id" : ObjectId("5a07ff40699a3774b04612c5"), "country" : "china",
"province" : "bj", "userid" : "da" }
{ "_id" : ObjectId("5a07ff40699a3774b04612c6"), "country" : "china",
"province" : "bj", "userid" : "fa" }
> db.tv3.aggregate(
{$group : {_id : {country : '$country', province :'$province'}}}
)
{ "_id" : { "country" : "china", "province" : "bj" } }
{ "_id" : { "country" : "china", "province" : "sn" } }
> db.tv3.aggregate(
{$group : {_id : {country : '$country', province :'$province', userid : '$userid'}}}
)
{ "_id" : { "country" : "china", "province" : "bj", "userid" : "fa" } }
{ "_id" : { "country" : "china", "province" : "bj", "userid" : "da" } }
{ "_id" : { "country" : "china", "province" : "sh", "userid" : "b" } }
{ "_id" : { "country" : "china", "province" : "sh", "userid" : "c" } }
{ "_id" : { "country" : "china", "province" : "sh", "userid" : "a" } }
> db.tv3.aggregate(
{$group : {_id : {country : '$country', province :'$province',
userid : '$userid' } } },
{$group : {_id : {country : '$_id.country', province : '$_id.province'} } }
)
{ "_id" : { "country" : "china", "province" : "sh" } }
{ "_id" : { "country" : "china", "province" : "bj" } }
> db.tv3.aggregate(
{$group : {_id : {country : '$country', province :'$province',
userid : '$userid' } } },
{$group : {_id : {country : '$_id.country', province : '$_id.province'},
count : {$sum : 1 } } }
)
{ "_id" : { "country" : "china", "province" : "sh" }, "conut" : 3 }
{ "_id" : { "country" : "china", "province" : "bj" }, "conut" : 2 }
// 统计出每个country/province下的userid的数量(同一个userid只统计一次)
> db.tv3.aggregate(
{$group : {_id : {country : '$country', province :'$province',
userid : '$userid' } } },
{$group : {_id : {country : '$_id.country', province : '$_id.province'},
count : {$sum : 1 } } },
{$project : {country : '$_id.country', province : '$_id.province',
count : 1, _id : 0 } }
)
{ "conut" : 3, "country" : "china", "province" : "sh" }
{ "conut" : 2, "country" : "china", "province" : "bj" }
>
- $match
用于过滤数据,只输出符合条件的文档
使用MongoDB的标准查询操作
match是管道命令,能将结果交给后一个管道,但是find不可以
> db.stu.aggregate(
{$match : {age : {$gt : 20}}},
{$group : {_id : "$gender", count : {$sum : 1}}},
{$project : {_id : 0, gender : "$_id", count : 1}}
)
{ "count" : 2, "gender" : true}
> db.stu.aggregate(
{$match : {age : {$gte : 18}}},
{$group : {_id : "$gender", count : {$sum : 1}}},
{$project : {_id : 0, gender : "$_id", count : 1}}
)
{ "count" : 2, "gender" : false}
{ "count" : 4, "gender" : true}
> db.stu.aggregate(
{$match : {$or : [{age : {$gte : 20}}, {hometown :
{$in : ["蒙古", "大理"] } } ] } }
{$group : {_id : "$gender", count : {$sum : 1}}},
{$project : {_id : 0, gender : "$_id", count : 1}}
)
{ "count" : 1, "gender" : false}
{ "count" : 4, "gender" : true}
- $project
修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
> db.stu.aggregate(
{$group : {_id : "$gender", count : {$sum : 1}, avg_age : {$avg : "$age"}}},
{$project : {gender : "$_id", count : "$count", avg_age : "$avg_age"}}
)
{"_id" : false, "gender" : false, "count" : 2, "avg_age": 18}
{"_id" : true, "gender" : true, "count" : 5, "avg_age": 27.8}
> db.stu.aggregate(
{$group : {_id : "$gender", count : {$sum : 1}, avg_age : {$avg : "$age"}}},
{$project : {gender : "$_id", count : 1, avg_age : "$avg_age", _id : 0}}
)
{"count" : 2, "gender" : false, "avg_age": 18}
{"count" : 5, "gender" : true, "avg_age": 27.8}
- $sort
将输入文档排序后输出
> db.stu.find()
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.aggregate(
{$group : {_id : "$gender", count : {$sum : 1}}}, {$sort : {count : -1}}
)
{ "_id" : true, "count" : 5}
{ "_id" : false, "count" : 2}
- $limit和$skip
$limit : 限制聚合管道返回的文档数
> db.stu.aggregate({$limit : 2})
{"_id" : ObjectId("5a0401d5507a7101e4eaa600"), "name" : "郭靖", "hometown" : "蒙古",
"age" : 20, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa601"), "name" : "黄蓉", "hometown" : "桃花岛",
"age" : 18, "gender" :false }
$skip : 跳过指定数量的文档,并返回余下的文档
> db.stu.aggregate({$skip : 2})
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa604"), "name" : "段誉", "hometown" : "大理",
"age" : 16, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa605"), "name" : "段王爷", "hometown" : "大理",
"age" : 45, "gender" : true }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "洪七公", "hometown" : "华山",
"age" : 18, "gender" : true }
> db.stu.aggregate({$skip : 2}, {$limit : 2})
{"_id" : ObjectId("5a0401d5507a7101e4eaa602"), "name" : "华筝", "hometown" : "蒙古",
"age" : 18, "gender" : false }
{"_id" : ObjectId("5a0401d5507a7101e4eaa603"), "name" : "黄药师", "hometown" : "桃花岛",
"age" : 40, "gender" : true }
- $unwind
将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
db.集合名称.aggregate({$unwind : "$字段名称"})
> db.t2.find()
{ "_id" : 1, "item" : 't-shirt', "size" : ['S', 'M', 'L']}
> db.t2.aggregate({$unwind : "$size"})
{ "_id" : 1, "item" : "t-shirt", "size" : "S" }
{ "_id" : 1, "item" : "t-shirt", "size" : "M" }
{ "_id" : 1, "item" : "t-shirt", "size" : "L" }
// 数据库中有一条数据:{"username":"Alex","tags": ['C#','Java','C++']},
// 如何获取该tag列表的长度
> db.t2.insert({"username":"Alex","tags": ['C#','Java','C++']})
WriteResult({ "nInserted" : 1})
> db.t2.find()
{ "_id" : 1, "item" : 't-shirt', "size" : ['S', 'M', 'L']}
{ "_id" : Object("5a604b132b127e7d06559e98"), "username" : "Alex",
"tags": ['C#', 'Java', 'C++'] }
> db.t2.aggregate(
{$match : {username : "Alex"}},
{$unwind : "$tags"}
)
{ "_id" : Object("5a604b132b127e7d06559e98"), "username" : "Alex", "tags" : 'C#' }
{ "_id" : Object("5a604b132b127e7d06559e98"), "username" : "Alex", "tags" : 'Java' }
{ "_id" : Object("5a604b132b127e7d06559e98"), "username" : "Alex", "tags" : 'C++' }
> db.t2.aggregate(
{$match : {username : "Alex"}},
{$unwind : "$tags"},
{$group : {_id : null, sum : {$sum : 1}}}
)
{ "_id" : null, "sum" : 3 }
属性preserveNullAndEmptyArrays值为false表示丢弃属性值为空的文档
属性preserveNullAndEmptyArrays值为true表示保留属性值为空的文档
> db.t3.find()
{ "_id" : 1, "item" : "a", "size": [ "S", "M", "L"] }
{ "_id" : 2, "item" : "b", "size" : [ ] }
{ "_id" : 3, "item" : "c", "size": "M" }
{ "_id" : 4, "item" : "d" }
{ "_id" : 5, "item" : "e", "size" : null }
> db.t3.aggregate(
{$unwind : "$size"}
)
{ "_id" : 1, "item" : "a", "size": "S" }
{ "_id" : 1, "item" : "a", "size": "M" }
{ "_id" : 1, "item" : "a", "size": "L" }
{ "_id" : 3, "item" : "c", "size": "M" }
> db.t3.aggregate(
{$unwind :
{path : "$size"}
}
)
{ "_id" : 1, "item" : "a", "size": "S" }
{ "_id" : 1, "item" : "a", "size": "M" }
{ "_id" : 1, "item" : "a", "size": "L" }
{ "_id" : 3, "item" : "c", "size": "M" }
> db.t3.aggregate(
{$unwind :
{path : "$size",
preserveNullAndEmptyArrays : true
}
}
)
{ "_id" : 1, "item" : "a", "size": "S" }
{ "_id" : 1, "item" : "a", "size": "M" }
{ "_id" : 1, "item" : "a", "size": "L" }
{ "_id" : 2, "item" : "b" }
{ "_id" : 3, "item" : "c", "size": "M" }
{ "_id" : 4, "item" : "d" }
{ "_id" : 5, "item" : "e", "size" : null }
六、索引
1、创建索引
- 索引:以提升查询速度
db.集合.ensureIndex({属性 : 1}) // 1表示升序, -1表示降
> db.t255.find().count()
100000
> db.t255.find({ name : "test10000"})
{ "_id" : ObjectId("5a6050132b127e7d0655c5a9"), "name" : "test10000", "age" : 10000 }
> db.t255.find({name : "test10000"}).explain("executionStats")
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 34,
"totalKeysExamined" : 0
}
> db.t255.ensureIndex({name : 1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.t255.find({name : "test10000"}).explain("executionStats")
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 0,
"totalKeysExamined" : 1
}
2、索引
- 查看当前集合的所有索引
db.集合.getIndexes()
> db.t255.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
}
"name" : "_id_"
"ns" : "test.t255"
},
{
"v" : 2,
"key" : {
"name" : 1
}
"name" : "name_1"
"ns" : "test.t255"
}
]
- 删除索引
db.集合.dropIndex({'索引名称' : 1})
> db.t255.dropIndex({name : 1})
{ "nIndexesWas" : 2, "ok" : 1}
> db.t255.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
}
"name" : "_id_"
"ns" : "test.t255"
}
]
- 创建唯一索引(索引的值是唯一的)
db.集合.ensureIndex({"索引名称" : 1}, {"unique" : true})