MongoDB数据库,账号增删改,库的相关操作(增删查),集合(表)的相关操作,文档(记录)相关操作,python连接MongoDB

简介

分布式非关系型数据库 nosql数据库
用于爬虫的数据存储,大数据方向
mongoDB是最像关系型的非关系型数据,更加适用于大数据,redis则更倾向于,并发较小,数据较小,性能更高

功能全
MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供了一系列不断扩展的独特功能

1、索引
支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引、全文索引

2、聚合
支持聚合管道,用户能通过简单的片段创建复杂的集合,并通过数据库自动优化

3、特殊的集合类型
支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话session。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志

4、文件存储
支持一种非常易用的协议,用于存储大文件和文件元数据。MongoDB并不具备一些在关系型数据库中很普遍的功能,如链接join和复杂的多行事务。省略
这些的功能是处于架构上的考虑,或者说为了得到更好的扩展性,因为在分布式系统中这两个功能难以高效地实现
# MongoDB概念
mongoDB        mysql
数据库         数据库
集合             表
文档(类似字典)   记录
键值对          字段


# MongoDB注意事项
#1、文档中的键/值对是有序的。
#2、文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
#3、MongoDB区分类型和大小写。
#4、MongoDB的文档不能有重复的键。
#5、文档中的值可以是多种不同的数据类型,也可以是一个完整的内嵌文档。文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。


# 文档键命名规范:
#1、键不能含有\0 (空字符)。这个字符用来表示键的结尾。
#2、.和$有特别的意义,只有在特定环境下才能使用。
#3、以下划线"_"开头的键是保留的(不是严格要求的)。

下载与安装

安装时去除多余的组件安装提高速度:

# 下载
官网: https://mongoDB.com
下载地址:https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-4.0.8-signed.msi


安装:直接下一步安装,中间不要下载组件,加快安装

 

 

 使用MongoDB

无账号密码登陆

cmd使用,切换到安装MongoDB路径的bin文件下,启动mongo.exe

如图,说明登陆成功,默认最高权限,无账号密码登陆

账号密码登陆

 创建账号

# 通过集合来确定所创用户的权限
use admin  # 先切换到admin集合里(最高权限)
db.createUser(
  {
    user: "root", # 创建账号
    pwd: "123", # 创建密码
    roles: [ { role: "root", db: "admin" } ]  # root表示可以执行任何操作,admin 表示用户只能操作admin集合
  }
)
use test
# 先切换到test集合里 # 用户操作多集合,(操作多库) db.createUser( { user: "lxx", # 创建账号 pwd: "123", # 创建密码 roles: [ { role: "readWrite", db: "test" }, # readWrite表示可以执行 读写 操作,test 表示用户只能操作test集合 { role: "read", db: "db1" } # # read表示用户可以执行 读 操作,db1 表示用户只能操作db1集合 ] } ) 更多角色请见:https://www.cnblogs.com/SamOk/p/5162767.html



# eg:
use admin  # 先切换到admin集合里(最高权限)
db.createUser(
  {
    user: "root", # 创建账号
    pwd: "123", # 创建密码
    roles: [ { role: "root", db: "admin" } ]  # root表示可以执行任何操作,admin 表示用户只能操作admin集合
  }
)

修改配置文档,开启账号认证

注意:修改完以后重启MongoDB服务器!!!

# 修改配置文档mongod.cfg(找到启动MongoDB的路径下,找到mongod.cfg)
# 改成:(缩进跟原文档一样)
security:
    authorization: enabled

如图:

注意:修改完以后重启MongoDB服务器!!!

登陆MongoDB

show dbs
# 登录方式1:  authenticationDatabase指定数据库
mongo --port 27017 -u "root" -p "123" --authenticationDatabase "admin"

# 登录方式2:进入mongoDB后 use admin # 先切换到指定集合里 db.auth("root","123") # 显示1表示登陆成功,0表示登陆失败

账号增删改

# 创建账号
# 通过集合来确定所创用户的权限
use admin  # 先切换到admin集合里(最高权限)
db.createUser(
  {
    user: "root", # 创建账号
    pwd: "123", # 创建密码
    roles: [ { role: "root", db: "admin" } ]  # root表示可以执行任何操作,admin 表示用户只能操作admin集合
  }
)

# 删除账号
db.dropUser('用户名');

# 修改密码
db.changeUserPassword(用户名, 新密码);

库的相关操作(增删查)

# 创建库
use xx  # 有这个库切换到库里,没有则创建

# 查看库
show dbs  # 库里没有集合,不显示(实际已经创好了)

# 删除库
db.dropDatabase() # 删哪个库切换到哪个库执行,注意区分大小写

# > db.dropDatabase()
# { "dropped" : "xx", "ok" : 1 }  表示删库成功

show dbs # 查看所有库
db # 查看当前所在库

集合(表)的相关操作

# 创建集合:
db.user  # 创建了user集合

# 查看集合: 同样的数据集合中没有数据则 不会显示
show collections  # 查看当前库里的所有集合
show tables   # 查看当前库里的所有集合

# 删除集合:
# db.集合名.drop()
db.blog.user.drop() # 集合里有文档才能删集合

mongodb支持的数据类型

# null:用于表示空或不存在的字段
d={'x':null}

# 布尔型:true和false
d={'x':true,'y':false}

# 数值
d={'x':3,'y':3.1415926}

# 字符串
d={'x':'egon'}

# 日期
d={'x':new Date()}
d.x.getHours()

# 正则表达式,正则写在/.../内,后面的i代表:
d={'pattern':/^egon.*?nb$/i}  #
# i 忽略大小写
# m 多行匹配模式
# x 忽略非转义的空白字符
# s 单行匹配模式

# 数组
d={'x':[1,'a','v']}

# 内嵌文档
user={'name':'jerry','addr':{'country':'China','city':'YT'}}
user.addr.country

# 对象id:是一个12字节的ID,是文档的唯一标识,不可变
d={'x':ObjectId()}

db.a.insert(d)  # 插入上述文档

文档(记录)操作

插入

# 插入一条 insert
db.user.insert({"_id":1})

# 插入多条 insertMany
db.user.insertMany([
    {"_id":3,"name":"张三封"},
    {"_id":4,"name":"鹌鹑蛋"}
])

# 插入变量 insert
var user1 = {"_id":10,"name":"王五"} # 先定义一个变量   var可以省略  #
var user2 = {"_id":11,"name":"王六"} # 先定义一个变量   var可以省略  #
db.user.insert(user1)  # 再插入一个变量
db.user.insertMany([user1,user2])  # 再插入多个变量

# save方法,覆盖集合
# db.user.save( {"_id":10,"name":"鹌鹑蛋2"})  # 如果id已经存在则覆盖,没有添加,相当于先清空原集合里的文档,在设置新文档

# 插入布尔值
# {'key':null} 匹配key的值为null或者没有这个key
db.t2.insert({'a':10,'b':111})
db.t2.insert({'a':20})
db.t2.insert({'b':null})

查询文档(记录)

# db.student.find({},{}}) 第一个字典参数表示查询所有的集合,第二个字典参数表示显示的字段
# find  # 查找所有匹配数据
# findOne  # 查找第一个匹配的
# pretty() # 文档格式化显示

# find 与 findone
db.user.find().pretty() # 查询user集合里的所有文档,相当于 select *from user db.user.findOne({"name":"张三"}) # 查询名字叫张三的第一个文档 db.user.find({"name":"张三"}) # 查询名字叫张三的文档,相当于 select *from user where name = "张三封" db.user.find({"name":"张三封","_id":3}) # 查询名字叫张三且id为3的文档,相当于 select *from user where name = "张三封 and _id = 3"
# 比较符查询 != > < >= <= "$ne","$gt","$lt","gte","lte" db.user.find({"name":{"$ne":"张三"}}) # 查询user集合里名字不叫张三的文档
# 逻辑运算符查找and,or,not # and查询 db.user.find({'_id':{"$gte":2,"$lt":4}}) # 查询id>=2,且小于4的文档 db.user.find({"_id":{"$gte":2},"age":{"$lt":40}}) # 查询id>=2,且年龄<40的文档 # or 查询 db.user.find( # 查询id大于5,或者name是cxx的文档 {"$or":[{'_id':{"$gte":5}},{"name":"cxx"}]} ) # not查询 {"$mod":[2,1]} mod表示取余,除以2余1 db.user.find({'_id':{"$not":{"$mod":[2,1]}}}) # 查询id不是奇数的文档 # "$in","$nin" 成员查询 db.user.find({"age":{"$in":[20,30,31]}}) # 查看年龄在[20,30,31]的文档 db.user.find({"name":{"$nin":['alex','yuanhao']}}) 查看名字不是alex,yuanhao的文档
# /正则表达式/ 正则查询 db.user.find({'name':/^j.*?(g|n)$/i}) # 查询以j开头,g或n结尾的文档(忽略大小写) # i 忽略大小写 # m 多行匹配模式 # x 忽略非转义的空白字符 # s 单行匹配模式
# 指定字段查询 db.user.find({'_id':3},{'_id':0,'name':1,'age':1}) # 查询id为3的文档,只显示name,age,其它字段都不显示 # 0表示不显示 默认为0 1为显示
# 数组查询 db.user.find({'hobbies':'dancing'}) # 查询有爱好为 dancing的文档 # $all 查询 db.user.find({ # 查询爱好有dancing,tea的文档 'hobbies':{ "$all":['dancing','tea'] } }) # 通过$size获取数组的长度,但是$size不能和比较操作符联合使用 db.user.find({},{"hobbies":{"$size":3}}) # 查询拥有三个爱好的用户文档 # 数组索引查询 db.user.find({},{"hobbies.3":'tea'}) # 查询第四个爱好为tea的文档 # 数组切片查询 # $slice [1,1] 表示的是从第1个开始取1个 db.student.find({},{"hobbies":{"$slice":[1,1]}}).pretty() # 表示查看学生集合的第二个爱好 db.student.find({},{"hobbies":{"$slice":[2,2]}}).pretty() # 表示查看学生集合的 第二个,第三个 爱好的文档 db.student.find({},{"hobbies":{"$slice":[0,1]}}).pretty() # 表示查看学生集合的第一个爱好 db.student.find({},{"hobbies":{"$slice":[-1]}}).pretty() # 表示查看学生集合的最后一个爱好 db.student.find({},{"hobbies":{"$slice":[-2]}}).pretty() # 表示查看学生集合的最后两个爱好 # 排序升序显示,1代表升序,-1代表降序 db.user.find().sort({"name":1,}) # user集合的name字段升序显示 db.user.find().sort({"age":-1,'_id':1}) # user集合的age字段降序显示,id字段升序显示 # 分页查询,limit代表取多少个document,skip代表跳过前多少个document。 # 先排好序,在分页查询 db.user.find().sort({'age':1}).limit(1).skip(2) # 查询年龄第三名的user文档 db.user.find().limit(1).skip(2) # 查询第三条文档
# 数量查询 count db.user.count({'age':{"$gt":30}}) # 查询年龄大于三十的文档个数 db.user.find({'age':{"$gt":30}}).count() # 查询年龄大于三十的文档个数
# 布尔查询 db.t2.insert({'a':10,'b':111}) db.t2.insert({'a':20}) db.t2.insert({'b':null}) # db.t2.find({"b":null}) { "_id" : ObjectId("5a5cc2a7c1b4645aad959e5a"), "a" : 20 } { "_id" : ObjectId("5a5cc2a8c1b4645aad959e5b"), "b" : null } # 查询没有b字段,或者b字段为空的文档

更新文档

# update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
参数说明:对比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18;

query : 相当于where条件。
update : update的对象和一些更新的操作符(如$,$inc...等,相当于set后面的
upsert : 可选,默认为false,代表如果不存在update的记录不更新也不插入,设置为true代表插入。
multi : 可选,默认为false,代表只更新找到的第一条记录,设为true,代表更新找到的全部记录。
writeConcern :可选,抛出异常的级别。

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


# 覆盖式更新:(少用) 注意:除非是删除,否则_id是始终不会变的
db.user.update({'age':20},{"name":"Wxx","hobbies_count":3}) # 将age=20的文档全部替换为 {"name":"Wxx","hobbies_count":3}
# 是用{"_id":2,"name":"Wxx","hobbies_count":3}覆盖原来的记录


# 一种最简单的更新就是用一个新的文档完全替换匹配的文档。这适用于大规模式迁移的情况。例如
var obj=db.user.findOne({"_id":2}) # 设置一个新的变量
obj.username=obj.name+'SB'   # 添加username字段
obj.hobbies_count++   # hobbies_count字段自加一
delete obj.age  # 删除age字段

db.user.update({"_id":2},obj)  # 更新完以后的文档为 {"_id":2,"username":"usernameSB"}


# $set 更新具体某些字段
db.user.update({'_id':2},{"$set":{"name":"WXX",}})  # 将id为2的文档的 name字段更新为 WXX


# {"upsert":true} 有则更新,没有某一条文档,则添加这条文档,
db.user.update({'_id':6},{"$set":{"name":"egon","age":18}},{"upsert":true})


# {"multi":true} 默认只改匹配成功的第一条
db.user.update({'_id':{"$gt":4}},{"$set":{"age":28}})  # 只改id大于4的第一条文档
db.user.update({'_id':{"$gt":4}},{"$set":{"age":38}},{"multi":true})  # id大于4的文档全部更新


# 修改内嵌文档,把名字为alex的人所在的地址国家改成Japan
db.user.update({'name':"alex"},{"$set":{"addr.country":"Japan"}})
db.user.update({'name':"alex"},{"$set":{"hobbies.1":"piao"}})  # 把名字为alex的文档的第二个爱好改成piao
$unset 删除文档指定字段
db.user.update({'name':"alex"},{"$unset":{"hobbies":""}}) # 把名字为alex的文档的hobbies字段删除掉

$inc 增加 与 $i 减少

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

数组相关操作

# 往数组内添加元素:$push
    # 添加一个爱好
    db.user.update({"name":"yuanhao"},{"$push":{"hobbies":"read"}})  # 为名字为yuanhao的人添加一个爱好read
    # 添加多个爱好
    db.user.update({"name":"yuanhao"},{"$push":{   # 为名字为yuanhao的人一次添加多个爱好tea,dancing
        "hobbies":{"$each":["tea","dancing"]}
    }})

# 按照位置且只能从开头或结尾删除元素:$pop # {"$pop":{"key":1}} 从数组末尾删除一个元素 db.user.update({"name":"yuanhao"},{"$pop":{ # 删除文档的最后一种爱好 "hobbies":1} })
# {"$pop":{"key":-1}} 从头部删除 db.user.update({"name":"yuanhao"},{"$pop":{ # 删除文档的第一种爱好 "hobbies":-1} })
# 按照条件删除元素,:"$pull" 把符合条件的统统删掉,而$pop只能从两端删 db.user.update({'addr.country':"China"},{"$pull":{ # 把位于中国的文档删除read的爱好 "hobbies":"read"} },{ "multi":true} )

删除文档

# deleteOne 删除一条文档
db.user.deleteOne({ 'age': 8 })  # 删除age字段为8的第一条文档

# deleteMany 删除多条文档 db.user.deleteMany( {'addr.country': 'China'} ) # 把国家 为 "china" 的所有文档删除 db.user.deleteMany({}) # 删除集合里的全部文档
# $unset 删除文档指定字段 db.user.update({'name':"alex"},{"$unset":{"hobbies":""}}) # 把名字为alex的文档的hobbies字段删除掉

自动去除重复 $addToSet

db.urls.insert({"_id":1,"urls":[]})
db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
# 将连接地址去重
db.urls.update({"_id":1},{
    "$addToSet":{
        "urls":{
        "$each":[
            'http://www.baidu.com',
            'http://www.baidu.com',
            'http://www.xxxx.com'
            ]
            }
        }
    }
)

python连接MongoDB

from pymongo import MongoClient

# 方法一:
client = MongoClient("mongodb://root:123@127.0.0.1:27017")  # 建立连接

table = client['jd_db']['aa']  # 切换到表
# print(table.collection_names(include_system_collections=False))  # 不显示系统集合的名字 include_system_collections=False为不显示

table_data = table.insert({"name": "cxx", "age": 16}, {"sex": ""})   # 插入
table.update({"name":"cxx"},{"$set":{"name":"yyy"}})  # 更新
table.delete_many({"name":"yyy"})  # 删除
print(list(table.find()))




# 方法二:
client = MongoClient(host="127.0.0.1", port=27017)  # 连接mongodb数据库
table = client["admin"]  # 切到admin表
table.authenticate(name="root", password="123")  # 验证账号,密码
# print(table.collection_names(include_system_collections=False))  # 不显示系统集合的名字

if table:  # 验证通过
    table = client["jd_db"]["aa"]  # 切换到相应的表里执行操作
    print(list(table.find()))
# 3、查看库下所有的集合
print(db.collection_names(include_system_collections=False))

#4、创建集合
table_user=db['userinfo'] #等同于:db.user

#5、插入文档
import datetime
user0={
    "_id":1,
    "name":"egon",
    "birth":datetime.datetime.now(),
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'BJ'
    }
}

user1={
    "_id":2,
    "name":"alex",
    "birth":datetime.datetime.now(),
    "age":10,
    'hobbies':['music','read','dancing'],
    'addr':{
        'country':'China',
        'city':'weifang'
    }
}
res=table_user.insert_many([user0,user1]).inserted_ids   # 插入多条
# print(res)
# print(table_user.count())

#6、查找
# from pprint import pprint  # 格式化
# pprint(table_user.find_one())
# for item in table_user.find():
#     pprint(item)
print(table_user.find_one({"_id":{"$gte":1},"name":'egon'}))  # 查一条

#7、更新
table_user.update({'_id':1},{'name':'EGON'})

#8、传入新的文档替换旧的文档
table_user.save(   # 覆盖是更新
    {
        "_id":2,
        "name":'egon_xxx'
    }
)
posted @ 2019-04-16 08:27  星牧  阅读(434)  评论(0编辑  收藏  举报