文章目录
第二十七章 python操作mongo
今天我们学习mongodb剩下的知识点,我们上次学习了如何添加和删除数据,以及如何查询数据。我们继续学习如何修改数据。
1. mongo修改和删除
语法
db.集合的名称.update({query},{update},{multi:boolean})
第一个花括号里面的是条件,第二个花括号里的是更新的内容,第三个花括号里的是一个可选择条件,布尔值默认为假,只修改符合条件的第一个数据,如果设置为true则修改所有数据。
例子:我们把stu表里面的Jerry改成Tom
> db.stu.find()
{ "_id" : ObjectId("607546d0fe8b060d8a3fbfd9"), "name" : "张三", "age" : 17, "hometown" : "长沙", "gender" : "male" }
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : "male" }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : "male" }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Jerry", "age" : 30, "hometown" : "长沙", "gender" : "male" }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : "female" }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : "female" }
> db.stu.update({name:'Jerry'},{name:'Tom'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find()
{ "_id" : ObjectId("607546d0fe8b060d8a3fbfd9"), "name" : "张三", "age" : 17, "hometown" : "长沙", "gender" : "male" }
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : "male" }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : "male" }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom" }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : "female" }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : "female" }
>
我们看到的确把Jerry改成了Tom,但同时删除了其他的数据,这是全部修改。
1.1 指定键值的更新
如何只修改名字而不动其他的数据呢?那就用到指定键值的更新修改$set{},下面我们只更新“张三”为“zhangsan”,其他的数据不变。
> db.stu.update({name:'张三'},{$set:{name:'zhangsan'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find()
{ "_id" : ObjectId("607546d0fe8b060d8a3fbfd9"), "name" : "zhangsan", "age" : 17, "hometown" : "长沙", "gender" : "male" }
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : "male" }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : "male" }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom" }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : "female" }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : "female" }
>
db.stu.update({name:‘张三’},{KaTeX parse error: Expected 'EOF', got '}' at position 22: …ame:'zhangsan'}}̲) 这个命令与之前相比多了{set: },里面是我们要设置的条件。
1.2 可选参数
{multi:boolean}是可选参数,默认为False,表示只更新找到的第一条数据。如果设置为true则把满足条件的全部数据更新。例如我们更新“zhangsan”的性别:
> db.stu.update({},{$set:{gender:0}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.stu.find()
{ "_id" : ObjectId("607546d0fe8b060d8a3fbfd9"), "name" : "zhangsan", "age" : 17, "hometown" : "长沙", "gender" : 0 }
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : "male" }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : "male" }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom" }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : "female" }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : "female" }
>
这样虽然前面是db.stu.update({}, ),代表适用于所有的数据,但是后面的multi:boolean默认为False,所以只更新了第一条数据。如果最后设置为true则所有数据都会更新。
> db.stu.update({},{$set:{gender:0}},{multi:true})
WriteResult({ "nMatched" : 6, "nUpserted" : 0, "nModified" : 5 })
> db.stu.find()
{ "_id" : ObjectId("607546d0fe8b060d8a3fbfd9"), "name" : "zhangsan", "age" : 17, "hometown" : "长沙", "gender" : 0 }
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : 0 }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : 0 }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom", "gender" : 0 }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : 0 }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : 0 }
我们发现name为Tom的数据也被插入了一个gender:0。就是说,如果有就修改,没有就给你加一个。
1.3 删除数据
命令
db.stu.remove({query})
# query是删除条件
比如我们把"zhangsan"这条数据删除了。
> db.stu.remove({name:'zhangsan'})
WriteResult({ "nRemoved" : 1 })
> db.stu.find()
{ "_id" : ObjectId("607546fdfe8b060d8a3fbfda"), "name" : "李四", "age" : 18, "hometown" : "武汉", "gender" : 0 }
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : 0 }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom", "gender" : 0 }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : 0 }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : 0 }
>
我们发现"zhangsan"没有了。
下面介绍仅仅删除满足条件的第一个justOne。
> db.stu.remove({age:18},{justOne:true})
WriteResult({ "nRemoved" : 1 })
> db.stu.find()
{ "_id" : ObjectId("6075472afe8b060d8a3fbfdb"), "name" : "王二", "age" : 29, "hometown" : "广州", "gender" : 0 }
{ "_id" : ObjectId("60754744fe8b060d8a3fbfdc"), "name" : "Tom", "gender" : 0 }
{ "_id" : ObjectId("60755423fe8b060d8a3fbfdd"), "name" : "amy", "age" : 18, "hometown" : "长沙", "gender" : 0 }
{ "_id" : ObjectId("607554e5d5dcd8aec2e26f44"), "name" : "anny", "age" : 19, "hometown" : "长沙", "gender" : 0 }
我们看到满足条件的两个数据,李四没有了,只剩下amy。
注意,justOne后面需要跟随一个布尔值true。当然你也可以justTwo,justThree等等,能just到多少自己去尝试吧。
总结:
- db.stu.remove({name:‘zhangsan’}) 带条件删除
- db.stu.remove({}) 删除所有
- db.stu.remove({age:18},{justOne:true}) 删除符合条件的第一个
- db.stu.drop() 删除表
2. 练习
下面是一些练习,回顾学过的操作。
1.查询年龄大于25小于27的name,age
2.查询出不是美国的name
3.查询国籍是中国或者美国的学生信息
4.查询语文成绩大于85或者英语成绩大于90的学生信息
5.查询出名字中存在"li"的学生信息
6.查询喜欢看MONGODB和PHP的学生
7.查询第二本书是JAVA的学生信息
8.查询喜欢的书数量是4本的学生
9.查询出persons中的国家分别是什么
2.1 添加数据
先把下面的数据添加到mongodb的demo里面。不要全部复制进去,先复制var persons,回车后再复制for循环,回车后再复制var persons = db.persons.find({name:“jim”}),回车后再复制while语句,然后回车。我们不需要纠结这些语句的语法,这是用js写的,我只录入数据,用来演示例子。
var persons = [{
name:"jim",
age:25,
email:"75431457@qq.com",
c:89,m:96,e:87,
country:"USA",
books:["JS","C++","EXTJS","MONGODB"]
},
{
name:"tom",
age:25,
email:"214557457@qq.com",
c:75,m:66,e:97,
country:"USA",
books:["PHP","JAVA","EXTJS","C++"]
},
{
name:"lili",
age:26,
email:"344521457@qq.com",
c:75,m:63,e:97,
country:"USA",
books:["JS","JAVA","C#","MONGODB"]
},
{
name:"zhangsan",
age:27,
email:"2145567457@qq.com",
c:89,m:86,e:67,
country:"China",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lisi",
age:26,
email:"274521457@qq.com",
c:53,m:96,e:83,
country:"China",
books:["JS","C#","PHP","MONGODB"]
},
{
name:"wangwu",
age:27,
email:"65621457@qq.com",
c:45,m:65,e:99,
country:"China",
books:["JS","JAVA","C++","MONGODB"]
},
{
name:"zhaoliu",
age:27,
email:"214521457@qq.com",
c:99,m:96,e:97,
country:"China",
books:["JS","JAVA","EXTJS","PHP"]
},
{
name:"piaoyingjun",
age:26,
email:"piaoyingjun@uspcat.com",
c:39,m:54,e:53,
country:"Korea",
books:["JS","C#","EXTJS","MONGODB"]
},
{
name:"lizhenxian",
age:27,
email:"lizhenxian@uspcat.com",
c:35,m:56,e:47,
country:"Korea",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lixiaoli",
age:21,
email:"lixiaoli@uspcat.com",
c:36,m:86,e:32,
country:"Korea",
books:["JS","JAVA","PHP","MONGODB"]
},
{
name:"zhangsuying",
age:22,
email:"zhangsuying@uspcat.com",
c:45,m:63,e:77,
country:"Korea",
books:["JS","JAVA","C#","MONGODB"]
}]
for(var i = 0;i<persons.length;i++){
db.persons.insert(persons[i])
}
var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}
for循环
for(var i = 0;i<persons.length;i++){
db.persons.insert(persons[i])
}
var persons = db.persons.find({name:“jim”})
while语句
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}
记得,有的win10系统是不能直接Ctrl+V粘贴到命令行的,你复制内容以后,在命令行窗口光标处右键一下就粘贴上了。
2.2 查询数据
我们用db.persons,find()查询一下数据:
> db.persons.find()
{ "_id" : ObjectId("6078f3e6e680e4d235aa2957"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2958"), "name" : "tom", "age" : 25, "email" : "214557457@qq.com", "c" : 75, "m" : 66, "e" : 97, "country" : "USA", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "age" : 26, "email" : "344521457@qq.com", "c" : 75, "m" : 63, "e" : 97, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "age" : 27, "email" : "2145567457@qq.com", "c" : 89, "m" : 86, "e" : 67, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "age" : 26, "email" : "274521457@qq.com", "c" : 53, "m" : 96, "e" : 83, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "age" : 27, "email" : "65621457@qq.com", "c" : 45, "m" : 65, "e" : 99, "country" : "China", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "age" : 27, "email" : "214521457@qq.com", "c" : 99, "m" : 96, "e" : 97, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295e"), "name" : "piaoyingjun", "age" : 26, "email" : "piaoyingjun@uspcat.com", "c" : 39, "m" : 54, "e" : 53, "country" : "Korea", "books" : [ "JS", "C#", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295f"), "name" : "lizhenxian", "age" : 27, "email" : "lizhenxian@uspcat.com", "c" : 35, "m" : 56, "e" : 47, "country" : "Korea", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli", "age" : 21, "email" : "lixiaoli@uspcat.com", "c" : 36, "m" : 86, "e" : 32, "country" : "Korea", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2961"), "name" : "zhangsuying", "age" : 22, "email" : "zhangsuying@uspcat.com", "c" : 45, "m" : 63, "e" : 77, "country" : "Korea", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
>
>
2.3 pretty查询
为了更美观,我们可以用pretty方法:
> db.persons.find().pretty()
{
"_id" : ObjectId("6078f3e6e680e4d235aa2957"), # 主key
"name" : "jim", # 姓名
"age" : 25, # 年龄
"email" : "75431457@qq.com", 邮箱
"c" : 89, # 中文成绩
"m" : 96, # 数学成绩
"e" : 87, # 英语成绩
"country" : "USA", # 国家
"books" : [
"JS",
"C++",
"EXTJS",
"MONGODB"
] # 喜欢的书
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa2958"),
"name" : "tom",
"age" : 25,
"email" : "214557457@qq.com",
"c" : 75,
"m" : 66,
"e" : 97,
"country" : "USA",
"books" : [
"PHP",
"JAVA",
"EXTJS",
"C++"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa2959"),
"name" : "lili",
"age" : 26,
"email" : "344521457@qq.com",
"c" : 75,
"m" : 63,
"e" : 97,
"country" : "USA",
"books" : [
"JS",
"JAVA",
"C#",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295a"),
"name" : "zhangsan",
"age" : 27,
"email" : "2145567457@qq.com",
"c" : 89,
"m" : 86,
"e" : 67,
"country" : "China",
"books" : [
"JS",
"JAVA",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295b"),
"name" : "lisi",
"age" : 26,
"email" : "274521457@qq.com",
"c" : 53,
"m" : 96,
"e" : 83,
"country" : "China",
"books" : [
"JS",
"C#",
"PHP",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295c"),
"name" : "wangwu",
"age" : 27,
"email" : "65621457@qq.com",
"c" : 45,
"m" : 65,
"e" : 99,
"country" : "China",
"books" : [
"JS",
"JAVA",
"C++",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295d"),
"name" : "zhaoliu",
"age" : 27,
"email" : "214521457@qq.com",
"c" : 99,
"m" : 96,
"e" : 97,
"country" : "China",
"books" : [
"JS",
"JAVA",
"EXTJS",
"PHP"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295e"),
"name" : "piaoyingjun",
"age" : 26,
"email" : "piaoyingjun@uspcat.com",
"c" : 39,
"m" : 54,
"e" : 53,
"country" : "Korea",
"books" : [
"JS",
"C#",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa295f"),
"name" : "lizhenxian",
"age" : 27,
"email" : "lizhenxian@uspcat.com",
"c" : 35,
"m" : 56,
"e" : 47,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"EXTJS",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa2960"),
"name" : "lixiaoli",
"age" : 21,
"email" : "lixiaoli@uspcat.com",
"c" : 36,
"m" : 86,
"e" : 32,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"PHP",
"MONGODB"
]
}
{
"_id" : ObjectId("6078f3e6e680e4d235aa2961"),
"name" : "zhangsuying",
"age" : 22,
"email" : "zhangsuying@uspcat.com",
"c" : 45,
"m" : 63,
"e" : 77,
"country" : "Korea",
"books" : [
"JS",
"JAVA",
"C#",
"MONGODB"
]
}
>
2.4 条件查询
1.查询年龄大于25小于27的name,age
db.persons.find({age:{$gt:25,$lt:27}},{name:1,age:1})
结果:
> db.persons.find({age:{$gt:25,$lt:27}},{name:1,age:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "age" : 26 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "age" : 26 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295e"), "name" : "piaoyingjun", "age" : 26 }
>
2.查询出不是美国的name,country
db.persons.find({country:{$ne:'USA'}},{name:1},{country:1})
结果
> db.persons.find({country:{$ne:'USA'}},{name:1,country:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "country" : "China" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "country" : "China" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "country" : "China" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "country" : "China" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295e"), "name" : "piaoyingjun", "country" : "Korea" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295f"), "name" : "lizhenxian", "country" : "Korea" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli", "country" : "Korea" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2961"), "name" : "zhangsuying", "country" : "Korea" }
3.查询国籍是中国或者美国的学生信息
db.persons.find({$or:[{country:'USA'},{country:'China'}]})
结果:
> db.persons.find({$or:[{country:'USA'},{country:'China'}]})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2957"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2958"), "name" : "tom", "age" : 25, "email" : "214557457@qq.com", "c" : 75, "m" : 66, "e" : 97, "country" : "USA", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "age" : 26, "email" : "344521457@qq.com", "c" : 75, "m" : 63, "e" : 97, "country" : "USA", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "age" : 27, "email" : "2145567457@qq.com", "c" : 89, "m" : 86, "e" : 67, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "age" : 26, "email" : "274521457@qq.com", "c" : 53, "m" : 96, "e" : 83, "country" : "China", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "age" : 27, "email" : "65621457@qq.com", "c" : 45, "m" : 65, "e" : 99, "country" : "China", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "age" : 27, "email" : "214521457@qq.com", "c" : 99, "m" : 96, "e" : 97, "country" : "China", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
>
4.查询语文成绩大于85或者英语成绩大于90的学生信息
db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{e:1,c:1,name:1})
结果
> db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{e:1,c:1,name:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2957"), "name" : "jim", "c" : 89, "e" : 87 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2958"), "name" : "tom", "c" : 75, "e" : 97 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "c" : 75, "e" : 97 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "c" : 89, "e" : 67 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "c" : 45, "e" : 99 }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "c" : 99, "e" : 97 }
>
5.查询出名字中存在"li"的学生信息
db.persons.find({name:/li/},{name:1})
结果
> db.persons.find({name:/li/},{name:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295f"), "name" : "lizhenxian" }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli" }
>
6.查询喜欢看MONGODB和PHP的学生
db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1,name:1})
结果
> db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1,name:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
>
7.查询第二本书是JAVA的学生信息
db.persons.find({'books.1':'JAVA'},{books:1})
结果
@(shell):1:26
> db.persons.find({'books.1':'JAVA'},{books:1,name:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2958"), "name" : "tom", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295f"), "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2961"), "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
>
8.查询喜欢的书数量是4本的学生
db.persons.find({books:{$size:4}},{books:1,name:1})
结果
> db.persons.find({books:{$size:4}},{books:1,name:1})
{ "_id" : ObjectId("6078f3e6e680e4d235aa2957"), "name" : "jim", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2958"), "name" : "tom", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2959"), "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295a"), "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295b"), "name" : "lisi", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295c"), "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295d"), "name" : "zhaoliu", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295e"), "name" : "piaoyingjun", "books" : [ "JS", "C#", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa295f"), "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2960"), "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "_id" : ObjectId("6078f3e6e680e4d235aa2961"), "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
>
9.查询出persons中的国家分别是什么
db.persons.distinct('country')
结果
> db.persons.distinct('country')
[ "China", "Korea", "USA" ]
>
2.5 命令总结
下面我们将以上的操作命令总结一下:
1.查询年龄大于25小于27的name,age
db.persons.find({age:{$gt:25,$lt:27}},{name:1,age:1})
2.查询出不是美国的name
db.persons.find({country:{$ne:'USA'}},{name:1})
3.查询国籍是中国或者美国的学生信息
db.persons.find({$or:[{country:'USA'},{country:'China'}]})
4.查询语文成绩大于85或者英语成绩大于90的学生信息
db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]},{e:1,c:1})
5.查询出名字中存在"li"的学生信息
db.persons.find({name:/li/},{name:1})
6.查询喜欢看MONGODB和PHP的学生
db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1})
7.查询第二本书是JAVA的学生信息
db.persons.find({'books.1':'JAVA'},{books:1})
8.查询喜欢的书数量是4本的学生
db.persons.find({books:{$size:4}},{books:1})
9.查询出persons中的国家分别是什么
db.persons.distinct('country')
3. mongo聚合命令
首先,什么是聚合,聚合是基于数据处理的聚合管道,每个文档通过一个由多个阶段组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。实际是在原来的操作的基础上还可以多一些操作。
3.1 常用的管道
$group:将集合中的文档分组,可用于统计结果
$match:过滤数据,只输出符合条件的文档
$sort:将输入文档排序后输出
$limit:限制聚合管道返回的文档数
$skip:跳过指定数量的文档,并返回余下的文档
3.2 测试数据
db.stu.insert({name:"a", hometown: '东北', age: 20, gender: true})
db.stu.insert({name:"b", hometown: '长沙', age: 18, gender: false})
db.stu.insert({name:"c", hometown: '武汉', age: 18, gender: false})
db.stu.insert({name:"d", hometown: '华山', age: 40, gender: true})
db.stu.insert({name:"e", hometown: '山东', age: 16, gender: true})
db.stu.insert({name:"f", hometown: '江苏', age: 45, gender: true})
db.stu.insert({name:"g", hometown: '大理', age: 18, gender: true})
我们可以再创建一个新的数据库juhe,然后写个循环插入以上数据:
var stu = [{name:"a", hometown: '东北', age: 20, gender: true},
{name:"b", hometown: '长沙', age: 18, gender: false},
{name:"c", hometown: '武汉', age: 18, gender: false},
{name:"d", hometown: '华山', age: 40, gender: true},
{name:"e", hometown: '山东', age: 16, gender: true},
{name:"f", hometown: '江苏', age: 45, gender: true},
{name:"g", hometown: '大理', age: 18, gender: true}]
# 循环插入
for(var i = 0;i<stu.length;i++){
db.stu.insert(stu[i])
}
结果
> use juhe
switched to db juhe
> var stu = [{name:"a", hometown: '东北', age: 20, gender: true},
... {name:"b", hometown: '长沙', age: 18, gender: false},
... {name:"c", hometown: '武汉', age: 18, gender: false},
... {name:"d", hometown: '华山', age: 40, gender: true},
... {name:"e", hometown: '山东', age: 16, gender: true},
... {name:"f", hometown: '江苏', age: 45, gender: true},
... {name:"g", hometown: '大理', age: 18, gender: true}]
> for(var i = 0;i<stu.length;i++){
... db.stu.insert(stu[i])
... }
WriteResult({ "nInserted" : 1 })
> db.stu.find()
{ "_id" : ObjectId("6079228d6900ff0c82a021f7"), "name" : "a", "hometown" : "东北", "age" : 20, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021f8"), "name" : "b", "hometown" : "长沙", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021f9"), "name" : "c", "hometown" : "武汉", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021fa"), "name" : "d", "hometown" : "华山", "age" : 40, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fb"), "name" : "e", "hometown" : "山东", "age" : 16, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fc"), "name" : "f", "hometown" : "江苏", "age" : 45, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fd"), "name" : "g", "hometown" : "大理", "age" : 18, "gender" : true }
> db.stu.count()
7
>
3.3 分组操作
$group
将集合中的文档分组,可用于统计结果
_id表示分组的依据,使用某个字段的格式为 ‘$字段’
根据性别分组
db.stu.aggregate({$group:{_id:'$gender'}})
结果
> db.stu.aggregate({$group:{_id:'$gender'}})
{ "_id" : true }
{ "_id" : false }
>
根据年龄分组
db.stu.aggregate({$group:{_id:'$age'}})
结果
> db.stu.aggregate({$group:{_id:'$age'}})
{ "_id" : 16 }
{ "_id" : 40 }
{ "_id" : 18 }
{ "_id" : 20 }
{ "_id" : 45 }
>
3.4 表达式
处理输⼊⽂档并输出
语法:表达式:’$列名’
常⽤表达式:
$sum: 计算总和, $sum:1 表示以⼀倍计数
$avg: 计算平均值
$min: 获取最⼩值
$max: 获取最⼤值
$push: 在结果⽂档中插⼊值到⼀个数组中
$first: 根据资源⽂档的排序获取第⼀个⽂档数据
$last: 根据资源⽂档的排序获取最后⼀个⽂档数据
3.5 分组中的聚合命令
统计男生有多少个,女生有多少个
db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1}}})
结果
> db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1}}})
{ "_id" : true, "stu_count" : 5 }
{ "_id" : false, "stu_count" : 2 }
stu_count()是一个方法,用来计数。后面的参数1是返回计数结果的倍数,如果是0,则返回结果是0。
> db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:2}}})
{ "_id" : true, "stu_count" : 10 }
{ "_id" : false, "stu_count" : 4 }
>
如果我想返回男生组和女生组的人名呢
db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1},name:{$push:'$name'}}})
结果
> db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1},name:{$push:'$name'}}})
{ "_id" : true, "stu_count" : 5, "name" : [ "a", "d", "e", "f", "g" ] }
{ "_id" : false, "stu_count" : 2, "name" : [ "b", "c" ] }
>
我们查找年龄大于20岁的,并且按照家乡分组
db.stu.aggregate({$match:{age:{$gt:20}}},{$group:{_id:'$hometown'}})
结果
> db.stu.aggregate({$match:{age:{$gt:20}}},{$group:{_id:'$hometown'}})
{ "_id" : "江苏" }
{ "_id" : "华山" }
>
只显示符合条件的第一个结果
db.stu.aggregate({$limit:1})
结果
> db.stu.aggregate({$limit:1})
{ "_id" : ObjectId("6079228d6900ff0c82a021f7"), "name" : "a", "hometown" : "东北", "age" : 20, "gender" : true }
>
跳过一个,并返回余下的结果
db.stu.aggregate({$skip:1})
结果
> db.stu.aggregate({$skip:1})
{ "_id" : ObjectId("6079228d6900ff0c82a021f8"), "name" : "b", "hometown" : "长沙", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021f9"), "name" : "c", "hometown" : "武汉", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021fa"), "name" : "d", "hometown" : "华山", "age" : 40, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fb"), "name" : "e", "hometown" : "山东", "age" : 16, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fc"), "name" : "f", "hometown" : "江苏", "age" : 45, "gender" : true }
{ "_id" : ObjectId("6079228d6900ff0c82a021fd"), "name" : "g", "hometown" : "大理", "age" : 18, "gender" : true }
>
下面我们将两个配合使用,在stu里面跳过一个数据,然后获取两个数据,即b和c
db.stu.aggregate({$skip:1},{$limit:2})
结果
> db.stu.aggregate({$skip:1},{$limit:2})
{ "_id" : ObjectId("6079228d6900ff0c82a021f8"), "name" : "b", "hometown" : "长沙", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021f9"), "name" : "c", "hometown" : "武汉", "age" : 18, "gender" : false }
>
如果这样写也是可以得到形同结果的:
> db.stu.aggregate({$limit:3},{$skip:1})
{ "_id" : ObjectId("6079228d6900ff0c82a021f8"), "name" : "b", "hometown" : "长沙", "age" : 18, "gender" : false }
{ "_id" : ObjectId("6079228d6900ff0c82a021f9"), "name" : "c", "hometown" : "武汉", "age" : 18, "gender" : false }
>
以上是分组中的聚合命令,总结一下:
db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1}}})
# 按照性别分组,并统计男女人数
db.stu.aggregate({$group:{_id:'$gender',stu_count:{$sum:1},name:{$push:'$name'}}})
# 按照性别分组,并统计男女人数,并返回姓名
db.stu.aggregate({$match:{age:{$gt:20}}},{$group:{_id:'$hometown'}})
# 符合年龄大于20岁的条件的数据,并按照家乡分组
db.stu.aggregate({$skip:1},{$limit:2})
# 跳过第一个数据,返回余下的前两个
4. mongo创建索引
mongodb的索引操作(拓展),可以加快查询速度。
如,我们先建一个表test,在里面插入10万条数据,可以这样写:
for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}
结果,用了44秒才出结果
> for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}
WriteResult({ "nInserted" : 1 })
> db.test.count()
100000
>
我们之前在show dbs的时候那几个数据库里的数据都显示为0,这次我们再显示一下
> show dbs
admin 0.000GB
config 0.000GB
demo 0.000GB
juhe 0.003GB
local 0.000GB
>
juhe里面的数据为 0.003GB了。我们切换到juhe
> use juhe
switched to db juhe
> show tables
stu
test
>
如果我们用find()命令,不会全部返回十万条数据,而只会先返回19条,如果我们需要更多,则输入it命令然后回车。
test
> db.test.find()
{ "_id" : ObjectId("607935fb6900ff0c82a021fe"), "name" : "test0", "age" : 0 }
{ "_id" : ObjectId("607935fb6900ff0c82a021ff"), "name" : "test1", "age" : 1 }
{ "_id" : ObjectId("607935fb6900ff0c82a02200"), "name" : "test2", "age" : 2 }
{ "_id" : ObjectId("607935fb6900ff0c82a02201"), "name" : "test3", "age" : 3 }
{ "_id" : ObjectId("607935fb6900ff0c82a02202"), "name" : "test4", "age" : 4 }
{ "_id" : ObjectId("607935fb6900ff0c82a02203"), "name" : "test5", "age" : 5 }
{ "_id" : ObjectId("607935fb6900ff0c82a02204"), "name" : "test6", "age" : 6 }
{ "_id" : ObjectId("607935fb6900ff0c82a02205"), "name" : "test7", "age" : 7 }
{ "_id" : ObjectId("607935fb6900ff0c82a02206"), "name" : "test8", "age" : 8 }
{ "_id" : ObjectId("607935fb6900ff0c82a02207"), "name" : "test9", "age" : 9 }
{ "_id" : ObjectId("607935fb6900ff0c82a02208"), "name" : "test10", "age" : 10 }
{ "_id" : ObjectId("607935fb6900ff0c82a02209"), "name" : "test11", "age" : 11 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220a"), "name" : "test12", "age" : 12 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220b"), "name" : "test13", "age" : 13 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220c"), "name" : "test14", "age" : 14 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220d"), "name" : "test15", "age" : 15 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220e"), "name" : "test16", "age" : 16 }
{ "_id" : ObjectId("607935fb6900ff0c82a0220f"), "name" : "test17", "age" : 17 }
{ "_id" : ObjectId("607935fb6900ff0c82a02210"), "name" : "test18", "age" : 18 }
{ "_id" : ObjectId("607935fb6900ff0c82a02211"), "name" : "test19", "age" : 19 }
Type "it" for more
输入it回车
> it
{ "_id" : ObjectId("607935fb6900ff0c82a02212"), "name" : "test20", "age" : 20 }
{ "_id" : ObjectId("607935fb6900ff0c82a02213"), "name" : "test21", "age" : 21 }
{ "_id" : ObjectId("607935fb6900ff0c82a02214"), "name" : "test22", "age" : 22 }
{ "_id" : ObjectId("607935fb6900ff0c82a02215"), "name" : "test23", "age" : 23 }
{ "_id" : ObjectId("607935fb6900ff0c82a02216"), "name" : "test24", "age" : 24 }
{ "_id" : ObjectId("607935fb6900ff0c82a02217"), "name" : "test25", "age" : 25 }
{ "_id" : ObjectId("607935fb6900ff0c82a02218"), "name" : "test26", "age" : 26 }
{ "_id" : ObjectId("607935fb6900ff0c82a02219"), "name" : "test27", "age" : 27 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221a"), "name" : "test28", "age" : 28 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221b"), "name" : "test29", "age" : 29 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221c"), "name" : "test30", "age" : 30 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221d"), "name" : "test31", "age" : 31 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221e"), "name" : "test32", "age" : 32 }
{ "_id" : ObjectId("607935fb6900ff0c82a0221f"), "name" : "test33", "age" : 33 }
{ "_id" : ObjectId("607935fb6900ff0c82a02220"), "name" : "test34", "age" : 34 }
{ "_id" : ObjectId("607935fb6900ff0c82a02221"), "name" : "test35", "age" : 35 }
{ "_id" : ObjectId("607935fb6900ff0c82a02222"), "name" : "test36", "age" : 36 }
{ "_id" : ObjectId("607935fb6900ff0c82a02223"), "name" : "test37", "age" : 37 }
{ "_id" : ObjectId("607935fb6900ff0c82a02224"), "name" : "test38", "age" : 38 }
{ "_id" : ObjectId("607935fb6900ff0c82a02225"), "name" : "test39", "age" : 39 }
Type "it" for more
如果我们要在这10万条数据里面找一个数据,比如test9999那么速度怎样呢:
> db.test.find({name:'test9999'})
{ "_id" : ObjectId("607936006900ff0c82a0490d"), "name" : "test9999", "age" : 9999 }
>
4.1 创建索引前查询速度
你自己感觉一下,好像没到一秒,我们用一个方法来测试一下:
db.test.find({name:'test9999'}).explain('executionStats')
输入上述命令,回车
> db.test.find({name:'test9999'}).explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "juhe.test",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "test9999"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "test9999"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 72,
"totalKeysExamined" : 0,
"totalDocsExamined" : 100000,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "test9999"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 100002,
"advanced" : 1,
"needTime" : 100000,
"needYield" : 0,
"saveState" : 100,
"restoreState" : 100,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 100000
}
},
"serverInfo" : {
"host" : "LAPTOP-Guanghui",
"port" : 27017,
"version" : "4.4.5",
"gitVersion" : "ff5cb77101b052fa02da43b8538093486cf9b3f7"
},
"ok" : 1
}
>
其中,这个参数
"executionTimeMillis" : 72,
是查询时间,这是创建索引前的查询时间,是72毫秒,是很快的,但是如果数据量巨大的情况下,查询速度就会受到影响。
4.2 创建索引
我们需要创建索引,这样可以提高查询速度,我们比较一下:
db.test.getIndexes() # 查询索引的命令
我们输入上述命令,回车
> db.test.getIndexes()
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
>
这是没有创建索引的查询结果。下面我们根据name创建索引
db.test.ensureIndex({name:1})
回车
> db.test.ensureIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
>
我们再输入查询索引命令
db.test.getIndexes()
回车
}
> db.test.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"name" : 1
},
"name" : "name_1"
}
]
>
得到了这样的结果。我们在创建索引之前,好像只有一个元素在类似列表的东西里面,但是创建索引之后,里面有两个元素。两个元素比较一下,是key里面的内容变了,变成了"name" : 1
4.3 创建索引后查询速度
我们再看看如果从中查询test9999时间有没有什么变化
输入
db.test.find({name:'test9999'}).explain('executionStats')
结果
> db.test.find({name:'test9999'}).explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "juhe.test",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "test9999"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"test9999\", \"test9999\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 2,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"test9999\", \"test9999\"]"
]
},
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "LAPTOP-Guanghui",
"port" : 27017,
"version" : "4.4.5",
"gitVersion" : "ff5cb77101b052fa02da43b8538093486cf9b3f7"
},
"ok" : 1
}
>
这次查询的 “executionTimeMillis” : 2,
也就是说,这次查询时间只用了2毫秒,查询速度提高了不少!真是这样吗?我们可以删除索引再试试。
4.4 删除索引
输入删除索引命令
db.test.dropIndex({name:1})
回车
> db.test.dropIndex({name:1})
{ "nIndexesWas" : 2, "ok" : 1 }
>
我们查看一下索引
> db.test.getIndexes()
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
>
又回到原来的状态,索引确实已经删除。那么我们再查询一下test9999
> db.test.find({name:'test9999'}).explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "juhe.test",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "test9999"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "test9999"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 68,
"totalKeysExamined" : 0,
"totalDocsExamined" : 100000,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "test9999"
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 1,
"works" : 100002,
"advanced" : 1,
"needTime" : 100000,
"needYield" : 0,
"saveState" : 100,
"restoreState" : 100,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 100000
}
},
"serverInfo" : {
"host" : "LAPTOP-Guanghui",
"port" : 27017,
"version" : "4.4.5",
"gitVersion" : "ff5cb77101b052fa02da43b8538093486cf9b3f7"
},
"ok" : 1
}
>
我们看显示时间的参数: “executionTimeMillis” : 68,
时间又回到了68毫秒,跟创建索引之前的72毫秒相近。由此证明了,创建索引确实大大提高了查询速度。这是为什么呢?原来,创建索引后,系统根据数据规律进行了排序,这样可以快速找到,就像我们读书时有个目录,就不必一页一页的翻去查找内容了,可以根据索引一下子找到第几页,道理时一样的。这个计数在大数据应用中是非常有价值的,比如你能在淘宝搜索栏输入商品名,回车后非常快的看到罗列出的商品,你可知道淘宝的数据库有多么庞大,但是并没有让你太久的等待,原因就在于此。
5. python操作mongo
下面我们用python操作一下mongodb。
第一 步:安装
C:\Users\MI>pip install pymongo
Collecting pymongo
Downloading pymongo-3.11.3-cp38-cp38-win_amd64.whl (383 kB)
|████████████████████████████████| 383 kB 544 kB/s
Installing collected packages: pymongo
Successfully installed pymongo-3.11.3
C:\Users\MI>
然后在pycharm里新建文件python操作mongo.py
在文件里导入pymongo然后连接:
# 导入模块
import pymongo
# 连接mongodb
mongo_client = pymongo.MongoClient()
我们按住Ctr点击MongoClient()进去看看:
在初始方法中有port和host,不过默认都是None。但上面有设置了
HOST = "localhost"
PORT = 27017
这就是主机号和端口号。所以是已经连接了的,如果你不放心,可以这样写:
mongo_client = pymongo.MongoClient(host=' 127.0.0.1',port=27017)
5.1 插入数据
下面我们插入数据
mongo_client['jerry']['student'].insert({'name':'jerry'})
两个方括号里,第一个是新的数据库名,第二个是新的表名,后面花括号里是插入的新数据。
下面我们show一下:
> show dbs
admin 0.000GB
config 0.000GB
demo 0.000GB
juhe 0.003GB
local 0.000GB
>
运行前是这样子的,我们运行一下python操作mongo.py文件,报了个错
D:/work/爬虫/Day29/python操作mongo.py:17: DeprecationWarning: insert is deprecated. Use insert_one or insert_many instead.
mongo_client['jerry']['student'].insert({'name':'jerry'})
说insert方法已经弃用,请用insert_one或insert_many来代替。这么快,老师讲课的时候还能用,现在就不能用了。那我们用insert_one试试,这次成功了
然后再show一下:
> show dbs
admin 0.000GB
config 0.000GB
demo 0.000GB
jerry 0.000GB
juhe 0.003GB
local 0.000GB
>
里面多了一个jerry数据库,我们切换到jerry数据库,然后查看一下我们刚插入的数据:
> db.student.find()
{ "_id" : ObjectId("607a3e30b0c8677a5dd2288c"), "name" : "jerry" }
{ "_id" : ObjectId("607a3e3d372618b66e99015d"), "name" : "jerry" }
>
可能是我们运行了两次的原因,里面插入了两条数据。
5.2 定义类操作mongo
我们也可以定义一个类来实现对mongo的操作
class MongoData():
# 在init方法中实现数据库的连接
def __init__(self,name):
self.client = pymongo.MongoClient(host='127.0.0.1',port=27017)
self.db = self.client['jerry'][name]
# 定义添加的方法
def add_one(self,data):
"""
:param data: 添加的数据
:return: 是否添加成功
"""
result = self.db.insert_one(data)
print(result)
if __name__ == '__main__':
md = MongoData('student')
r = md.add_one({'name':'abc'})
我们运行一下
D:\Python38\python.exe D:/work/爬虫/Day29/python操作mongo.py
<pymongo.results.InsertOneResult object at 0x0000019F0146CD40>
Process finished with exit code 0
打印出来一个pymongo对象
> db.student.find()
{ "_id" : ObjectId("607a3e30b0c8677a5dd2288c"), "name" : "jerry" }
{ "_id" : ObjectId("607a3e3d372618b66e99015d"), "name" : "jerry" }
{ "_id" : ObjectId("607a4bc817b7fa6f941ef8a8"), "name" : "abc" }
>
也可以返回一个id
print(result.inserted_id)
运行
607aa9bc130168eb329a3a73
我们再查询一下:
{ "_id" : ObjectId("607a3e30b0c8677a5dd2288c"), "name" : "jerry" }
{ "_id" : ObjectId("607a3e3d372618b66e99015d"), "name" : "jerry" }
{ "_id" : ObjectId("607a4bc817b7fa6f941ef8a8"), "name" : "abc" }
{ "_id" : ObjectId("607aa9bc130168eb329a3a73"), "name" : "abc" }
>
打印的正是最后一条数据的id
5.3 定义输入多个数据的方法
下面我们定义一个方法用来输入多条数据
def add_many(self,data):
'''
:param data: 添加的数据
:return:是否添加成功
'''
result = self.db.insert_many(data)
return result.inserted_ids
if __name__ == '__main__':
md = MongoData('student')
# r = md.add_one({'name':'abc'})
r = md.add_many([{'x':i} for i in range(2)])
print(r)
我们运行
[ObjectId('607aab681105d21b0fb86723'), ObjectId('607aab681105d21b0fb86724')]
两条数据的id已经打印出来,我们查询一下:
> db.student.find()
{ "_id" : ObjectId("607a3e30b0c8677a5dd2288c"), "name" : "jerry" }
{ "_id" : ObjectId("607a3e3d372618b66e99015d"), "name" : "jerry" }
{ "_id" : ObjectId("607a4bc817b7fa6f941ef8a8"), "name" : "abc" }
{ "_id" : ObjectId("607aa9bc130168eb329a3a73"), "name" : "abc" }
{ "_id" : ObjectId("607aab681105d21b0fb86723"), "x" : 0 }
{ "_id" : ObjectId("607aab681105d21b0fb86724"), "x" : 1 }
查询到新加了两条数据。
完整代码
# 导入模块
import pymongo
class MongoData():
# 在init方法中实现数据库的连接
def __init__(self,name):
self.client = pymongo.MongoClient(host='127.0.0.1',port=27017)
self.db = self.client['jerry'][name]
# 定义添加的方法
def add_one(self,data):
"""
:param data: 添加的数据
:return: 是否添加成功
"""
result = self.db.insert_one(data)
print(result.inserted_id)
def add_many(self,data):
'''
:param data: 添加的数据
:return:是否添加成功
'''
result = self.db.insert_many(data)
return result.inserted_ids
if __name__ == '__main__':
md = MongoData('student')
# r = md.add_one({'name':'abc'})
r = md.add_many([{'y':i} for i in range(2)])
print(r)
我们打印出结果
[ObjectId('607aaec5bd3bf017fa387d42'), ObjectId('607aaec5bd3bf017fa387d43')]
新添加的两条数据
> db.student.find()
{ "_id" : ObjectId("607a3e30b0c8677a5dd2288c"), "name" : "jerry" }
{ "_id" : ObjectId("607a3e3d372618b66e99015d"), "name" : "jerry" }
{ "_id" : ObjectId("607a4bc817b7fa6f941ef8a8"), "name" : "abc" }
{ "_id" : ObjectId("607aa9bc130168eb329a3a73"), "name" : "abc" }
{ "_id" : ObjectId("607aab681105d21b0fb86723"), "x" : 0 }
{ "_id" : ObjectId("607aab681105d21b0fb86724"), "x" : 1 }
{ "_id" : ObjectId("607aaec5bd3bf017fa387d42"), "y" : 0 }
{ "_id" : ObjectId("607aaec5bd3bf017fa387d43"), "y" : 1 }
>
大家可以用python来查询试一下怎么写代码。在总结里面有提示。
5.4 总结
Mongodb和Python的交互
pymongo安装
pip install pymongo
连接数据库
方式一
client = MongoClient()
方式二 指定端口和地址
client = MongoClient(‘localhost’,27017)
新增数据
from pymongo import MongoClient
from datetime import datetime
class TestMongo(object):
def __init__(self):
self.client = MongoClient('mongodb://localhost:27017/')
# 也可以指定连接的集合client['admin']['students']
self.db = self.client['admin']
# print(self.client.database_names())
def add_one(self):
post = {'title':'标题','content':'内容','created_at':datetime.now()}
# db.students students 是表明
res = self.db.students.insert_one(post)
return res
def add_more(self):
data_list = [{"name":"test{}".format(i)} for i in range(5)]
res = self.db.students.insert_many(data_list)
return res
mongo = TestMongo()
res = mongo.add_one()
#插入的ID
print(res.inserted_id)
#查询数据
from bson.objectid import ObjectId
#查询一条数据
def get_one(self):
return self.db.students.find_one()
#查询多条数据
def get_more(self):
return self.db.students.find()
#根据记录的ID查询数据
def get_from_id(self,id):
return self.db.students.find_one({'_id':ObjectId(id)})
#查询一条数据
res = mongo.get_one()
#查询多条数据
res = mongo.get_more()
for i in res:
print(i)
#根据记录的ID查询数据
res = mongo.get_from_id('5b83e8a1b594c32e8c70c1f7')
print(res)
#修改数据
#修改单条数据
def update(self):
res = self.db.students.update_one({'title':'标题'},{'$set':{'title':'title-2'}})
# 匹配的数据条数
print(res.matched_count)
# 影响的数据条数。
print(res.modified_count)
#修改多条
def update_more(self):
res = self.db.students.update_many({},{'$set':{'x':1}})
print(res.matched_count)
print(res.modified_count)
res = self.db.students.update({'x':2},{'$set':{'x':3}},True)
res = mongo.update()
res = mongo.update_more()
#删除数据
#删除一条
def delete_one(self):
res = self.db.students.delete_one({'title':'title-2'})
print(res.deleted_count)
#删除多条
def delete_more(self):
res = self.db.students.delete_many({'x':2})
print(res.deleted_count)
res = mongo.delete_one()
res = mongo.delete_more()
本次博客结束,如果喜欢别忘收藏点赞。