MongoDB和pymongo的CURD

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB和pymongo的CURD相关的知识,希望对你有一定的参考价值。

一、mongodb

1、介绍

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。


MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

 

 

2、下载安装

下载地址

3、mongodb的优势

 

4、几种常见的数据库

mysql    关系型数据库,数据保存磁盘上

redis    非关系型数据库,缓存在内存(可以持久化) 支持更丰富的数据类型
         key:value(value有五种类型:string list hash set Sorted Set)

memcache 非关系型数据库,缓存在内存  
         key:value(value必须是字符串)

mongodb  非关系型数据库,数据存储在磁盘上


mongodb与mysql的对比

       mysql                 mongodb
    database(数据库)        db (数据库) 
       table(表)            set(集合)   -->  结构:{{}, {}, {}, ...}
        记录                 文档 {}

 

二、mongodb的CURD

启动MongoDB

1、windows下启动MongoDB
1.启动服务器
- 打开命令窗口,切换到mongodb安装目录下的“bin”目录中(我的目录是:D:\\Tools\\MongoDB\\Server\\bin)
  cd D:\\Tools\\MongoDB\\Server\\bin

- 启动MongoDB服务
  mongod.exe --dbpath D:\\Tools\\MongoDB\\Server\\data

2.启动客户端
  cd D:\\Tools\\MongoDB\\Server\\bin
  mongo.exe

 

1、数据库操作

# 没有这个数据库则创建,有则切换到这个数据库
# 需要注意的是,新创建的数据库,在没有数据时,并不会真正创建
# 只有新建的数据库有了数据后,才会真正创建
> use t1
switched to db t1

# 展示所有数据库
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

# 新增一个集合(相当于mysql的表)并插入一个文档(相当于mysql的记录)
> db.article.insert({"title":"红楼梦"})
WriteResult({ "nInserted" : 1 })

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
t1      0.000GB

> show tables;
article

# 删除当前所选数据库
> db.dropDatabase()
{ "dropped" : "t1", "ok" : 1 }  

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB

 

2、集合操作

> use test2
switched to db test2

# 新增一个集合并插入文档
> db.school.insert({"title":"清华"})
WriteResult({ "nInserted" : 1 })
> db.school.insert({"title":"北大"})
WriteResult({ "nInserted" : 1 })

# 展示所有集合
> show tables;
school

# 删除集合
> db.school.drop()
true

> show tables;
>

 

三、文档操作

由于文档操作比较重要,单独拿出来

 

1、添加文档

# 1.没有指定_id则默认ObjectId,_id不能重复,且在插入后不可变
 
# 2.插入单条
user0={
    "name":"gouzi",
    "age":99,
    "hobbies":["gutou","rou"],
    "addr":{
        "country":"China",
        "city":"GZ"
    }
}

use userinfo;
db.test.insert(user0)
db.test.find()

# 3.插入多条
user1={
    "_id":1,
    "name":"xiaoming",
    "age":28,
    "hobbies":["girls","read","smoke"],
    "addr":{
        "country":"China",
        "city":"GuangZhou"
    }
}

user2={
    "_id":2,
    "name":"xiaohua",
    "age":18,
    "hobbies":["boys","drive","swim"],
    "addr":{
        "country":"China",
        "city":"DongGuan"
    }
}
 
user3={
    "_id":3,
    "name":"waimaige",
    "age":30,
    "hobbies":["food","drink"],
    "addr":{
        "country":"China",
        "city":"ShenZhen"
    }
}

user4={
    "_id":4,
    "name":"mangseng",
    "age":40,
    "hobbies":["moyan","rFlash","dancing","jiuren"],
    "addr":{
        "country":"China",
        "city":"waluolan"
    }
}

user5={
    "_id":5,
    "name":"tuoersuo",
    "age":50,
    "hobbies":["EEEE","happy","hasaki"],
    "addr":{
        "country":"China",
        "city":"aiouniya"
    }
}

db.user.insertMany([user1,user2,user3,user4,user5]) 
db.user.find()

 

2、查看文档

查找文档主要使用find()方法,find方法有两个参数,
第一个参数代表要筛选出来的文档,第二个参数是代表要展示的字段,
不写或者写空{} 代表全部

1. 比较运算
# SQL:     !=     >     <    >=    <=
# MongoDB:"$ne","$gt","$lt","gte","lte",其中"$ne"能用于所有数据类型

# 1、select * from db1.user where name = "xiaohua";
# 查找name=xioahua的文档
db.user.find({"name":"xiaohua"})
 
# 2、select * from db1.user where name != "xiaohua";
# 查找name!=xioahua的文档
db.user.find({"name":{"$ne":"xiaohua"}})
 
# 3、select * from db1.user where id > 2;
# 查找_id>2的文档
db.user.find({"_id":{"$gt":2}})
 
# 4、select * from db1.user where id < 3;
# 查找_id<3的文档
db.user.find({"_id":{"$lt":3}})
 
# 5、select * from db1.user where id >= 2;
# 查找_id>=2的文档
db.user.find({"_id":{"$gte":2,}})
 
# 6、select * from db1.user where id <= 2;
# 查找_id<=2的文档
db.user.find({"_id":{"$lte":2}})


2. 逻辑运算
# SQL:and,or,not
# MongoDB:字典中逗号分隔的多个条件是and关系,"$or","$not"
 
# 1、select * from db1.user where id >= 2 and id < 4;
db.user.find({"_id":{"$gte":2,"$lt":4}})
 
# 2、select * from db1.user where id >= 2 and age < 40;
db.user.find({"_id":{"$gte":2},"age":{"$lt":40}})
 
# 3、select * from db1.user where id >= 5 or name = "xiaohua";
db.user.find({"$or":[{"_id":{"$gte":5}},{"name":"xiaohua"}]})

# 4、select * from db1.user where id % 2=1;
db.user.find({"_id":{"$mod":[2,1]}})  # 就相当于取_id为奇数文档
 
# 5、上题,取反
db.user.find({"_id":{"$not":{"$mod":[2,1]}}})


3. 成员运算
# SQL:in,not in
# MongoDB:"$in","$nin"
 
# 1、select * from db1.user where age in (18,30,40);
db.user.find({"age":{"$in":[18,30,40]}})
 
# 2、select * from db1.user where name not in ("xiaohua","xiaoming");
db.user.find({"name":{"$nin":["xiaohua","xiaoming"]}})


4. 正则匹配
# SQL: regexp 正则
# MongoDB: /正则表达/i
 
# 1、select * from db1.user where name regexp "^x.*?(h|m)";
db.user.find({"name":/^x.*?(h|m)/i})


5. 取指定字段
第二个参数代表要展示的字段,1代表展示,0代表不展示

# 1、select name,age from db1.user where id=3;
db.user.find({"_id":3},{"name":1,"age":1})  # 查询_id=3的文档,只展示name和age字段

# 2、查询_id=3的文档,除了addr字段不展示,其他都展示
db.user.find({"_id":3},{"addr":0})

# 3、展示所有文档,只展示name字段
db.user.find({},{"name":1})

# 4、注意,1和0不能同时使用
#    因为1代表只展示这个字段,0代表除了这个字段都展示,因此会产生歧义
db.user.find({},{"name":1,"age":0})  # 这是错误的语法,是只展示name,还是除了age都展示

# 5、有种特殊的情况,1和0可以同时使用,就是_id为0可以跟其他字段的1一起使用
#    因为_id默认都是展示的,让_id为0可以让它不展示
db.userinfo.find({},{"name":1,"_id":0})  # 让默认展示的_id字段不展示


6. 查询数组
# 1、查看有drive爱好的人
db.user.find({"hobbies":"drive"})
 
# 2、查看既有drive爱好又有swim爱好的人
db.user.find({"hobbies":{"$all":["drive","swim"]}})
 
# 3、查看第2个爱好为drink的人
db.user.find({"hobbies.1":"drink"})
 
# 4、查看所有人最后两个爱好
db.user.find({},{"hobbies":{"$slice":-2},"age":0,"_id":0,"name":0,"addr":0})
 
# 5、查看所有人的第2个到第3个爱好
db.user.find({},{"hobbies":{"$slice":[1,2]},"age":0,"_id":0,"name":0,"addr":0})
 

7. 排序
# 1 代表升序,-1 代表降序
db.user.find().sort({"name":1,})  # 按name升序排序
db.user.find().sort({"age":-1,"_id":1})  # 按age降序排序,age相同的按_id升序排序


8. 分页
# 分页:--limit代表取多少个document,skip代表跳过前多少个document。
# 按age升序排序后,取两条文档,
db.user.find().sort({"age":1}).limit(2)

# 按age升序排序后,跳过前两条文档,显示剩下的文档
db.user.find().sort({"age":1}).skip(2)

# 按age升序排序后,跳过两条文档,取两条文档,即取第三、四条文档
db.user.find().sort({"age":1}).limit(2).skip(2)


9. 查询数量
# 查询age大于30的文档数
db.user.count({"age":{"$gt":30}})

或者

db.user.find({"age":{"$gt":30}}).count()


10. 其它
# 1、{"key":null} 匹配key的值为null或者没有这个key
db.test2.insert({"a":1,"b":2})
db.test2.insert({"a":10})
db.test2.insert({"b":null})
 
> db.test2.find({"b":null})
{ "_id" : ObjectId("5c4a7389f164aacd99e52430"), "a" : 10 }
{ "_id" : ObjectId("5c4a7390f164aacd99e52431"), "b" : null }

# 2、查找所有
db.user.find()  # 等同于db.user.find({})
db.user.find().pretty()  # 把结果格式化输出给我们看
 
# 3、查找一个,与find用法一致,只是只取匹配成功的第一个
db.user.findOne({"_id":{"$gt":3}})

 

3、修改文档

1. update的语法
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
参数说明
    query : 相当于where条件。
    update : update的对象和一些更新的操作符(如$,$inc...等,相当于set后面的
    upsert : 可选,默认为false,代表如果不存在update的记录不更新也不插入,设置为true代表插入。
    multi : 可选,默认为false,代表只更新找到的第一条记录,设为true,代表更新找到的全部记录。
    writeConcern :可选,抛出异常的级别。

更新操作是不可分割的:若两个更新同时发送,先到达服务器的先执行,然后执行另外一个,不会破坏文档。


2. 覆盖更新
# 注意:除非是删除,否则_id是始终不会变的
# 1、
db.user.update({"_id":3},{"name":"liqing","age":58,"long":18})
是用{"_id":3,"name":"liqing","long":18}覆盖原来的记录
 
# 2、一种最简单的更新就是用一个新的文档完全替换匹配的文档。这适用于大规模式迁移的情况。例如
var obj=db.user.findOne({"_id":3})

obj.name="SB"+obj.name
obj.long=obj.long-15
delete obj.age

db.user.update({"_id":3},obj)


3. 局部更新
# 设置:$set
通常文档只会有一部分需要更新。可以使用原子性的更新修改器,指定对文档中的某些字段进行更新。
更新修改器是种特殊的键,用来指定复杂的更新操作,比如修改、增加后者删除

# 1、update db1.user set name="xiazi" where id = 3
db.user.update({"_id":3},{"$set":{"name":"xiazi",}})  # 把_id为3的文档的name字段更改为 xiazi 

# $set既能修改某个文档的字段的值,也能给某个文档增加字段
db.user.update({"_id":3},{"$set":{"myname":"zbj"}})  # 给_id为3的文档增加一个myname字段
db.user.update({"_id":3},{"$set":{"addr.country":"China"}})  # 给_id为3的文档增加一个 addr 字段,addr是个字典,里面的键值对是 country: China

# 2、不存在的文档,update的记录不更新也不插入,upsert设置为true,则没有匹配成功就新增一条
db.user.update({"_id":6},{"$set":{"name":"VN","age":18}},{"upsert":true})

# 3、默认只改匹配成功的第一条,{"multi":改多条}
db.user.update({"_id":{"$gte":5}},{"$set":{"age":19}})
db.user.update({"_id":{"$gte":5}},{"$set":{"age":20}},{"multi":true})

# 4、修改内嵌文档,把名字为xiaoming的人所在的地址国家改成ZH
db.user.update({"name":"xiaoming"},{"$set":{"addr.country":"ZH"}})

#5、把名字为xiaoming的人的第2个爱好改成piao
db.user.update({"name":"xiaoming"},{"$set":{"hobbies.1":"piao"}})

#6、删除xiaoming的爱好,$unset
db.user.update({"name":"xiaoming"},{"$unset":{"hobbies":""}})  # 给要删除的字段任意值即可,会删除


4. 自增或自减
# 增加和减少:$inc

# 1、所有人年龄增加一岁
db.user.update({},{"$inc":{"age":1}},{"multi":true})

# 2、所有人年龄减少3岁
db.user.update({},{"$inc":{"age":-3}},{"multi":true})


5. 添加删除数组内元素
# 添加删除数组内元素:$push,$pop,$pull
# 往数组内添加元素:$push
# 1、为名字为tuoersuo的人添加一个爱好read
db.user.update({"name":"tuoersuo"},{"$push":{"hobbies":"read"}})
 
# 2、为名字为tuoersuo的人一次添加多个爱好tea,dancing
db.user.update({"name":"tuoersuo"},{"$push":{"hobbies":{"$each":["tong","tuo"]}}})
 
# 按照位置且只能从开头或结尾删除元素:$pop
# 3、{"$pop":{"key":1}} 从数组末尾删除一个元素
db.user.update({"name":"tuoersuo"},{"$pop":{"hobbies":1}})

# 4、{"$pop":{"key":-1}} 从头部删除
db.user.update({"name":"tuoersuo无法使用 pymongo 删除 mongodb 文档

带有日期时间的 MongoDB / Pymongo 查询

MongoDB Pymongo 问题

Python通过PyMongo库实现对MongoDB的使用

如何使用 pymongo 重命名 mongodb 数据库?

Pymongo / MongoDB:创建索引还是确保索引?