docker搭建mongodb及基本语法的使用
一、介绍:
概述:
主使用docker安装mongodb的方法记录,mongo基本语法记录的整理,大神请绕道!
优势:
1.MongoDB提供高性能的数据持久性。对嵌入式数据模型的支持减少了数据库系统上的IO活动
2.如动态模式、灵活的文档模型,适合json数据存储,适合海量数据存储
使用场景:
1.数据量大,读写操作频繁,数据价值较低,对事务要求不高;
2用于事件记录、内容管理、博客平台,电商,游戏;
3.存储用户信息,朋友圈信息,通过地理位置索引实现附近的人、定位功能等;
4.存储订单信息、订单状态、物流信息,订单状态在运送过程中飞速迭代、以MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更查出来;
二、搭建mongo:
1.pull镜像
docker pull mongo:4
ps:下载mongo镜像4的版本
2.创建映射文件的目录
mkdir -p /usr/local/mongodb/datadb
3.加载镜像运行容器
docker run -d \ --name mongodb \ -p 27017:27017 \ -v /usr/local/mongodb/datadb:/data/db \ -e MONGO_INITDB_ROOT_USERNAME=admin \ -e MONGO_INITDB_ROOT_PASSWORD=admin \ --privileged=true \ --restart always \ mongo:4
4.参数说明
-d 后台运行容器 --name mongodb 运行容器名(给容器取个名字) -p 27017:27017 将容器的27017端口映射到主机的27017端口(宿主机端口:容器端口) -v /usr/local/mongodb/datadb:/data/db 文件挂载目录(目录映射,好处:1.在宿主机直接共享数据到容器,2.容器删除后宿主机文件依然存在) -e MONGO_INITDB_ROOT_USERNAME=admin 指定用户名 -e MONGO_INITDB_ROOT_PASSWORD=admin 指定密码 --privileged=true 使得容器内的root拥有真正的root权限 --restart always 跟随docker一起启动,即docker启动时会自动运行容器
5.查看mongodb日志
docker logs mongodb
三、mongo的基本语法&用法
1.通用
#启动mongo cd /usr/local/mongodb/bin ./mongod -f mongodb.conf #以配置文件的方式启动MongoDB服务 ./mongo或者mongo #连接mongo数据库 #授权登录 use admin db.auth('user','password') #如果不授权就无法插入数据 show dbs; #查看所有数据库(当数据库无内容或未授权时,不显示库名) db 或db.getName(); #列出当前数据库 db.stats(); #查看当前数据库状态 db.version(); #查看当前数据库版本 db.getMongo(); #查看当前数据库链接机器 use 数据库名; #选择数据库(若库名存在切换数据库,若库名不存在则创建数据库) db.数据库.find().count(); #查询库的集合总数 db.name.drop() #删除集合 db.dropDatabase(); #删除当前库 db.createUser({user:"admin",pwd:"password",roles:["root"]}); #创建用户
#设置: db.adminCommand(nameOrDocument) #切换到'admin'数据库,并且运行命令 db.AddUser(username,password[, readOnly=false]) #添加用户 db.auth(usrename,password) #设置数据库连接验证 db.cloneDataBase(fromhost) #从目标服务器克隆一个数据库
2.查询
逻辑运算符:$eq:等于 $ne:不等于 $lt:小于 $lte:小于等于 $gt:大于 $gte:大于等于
#过滤-指定字段显示或不显示 db.dalan_test.find({"data._id":"86150"},{_id:0,"type":false}) #不显示_id和type字段 db.all_submit_data.find({"data._id":"86150"},{"_id":true,"type":true,"td-op-uid":true}) #先查询条件后,只显示_id,type,td-op-uid字段 db.all_submit_data.find({},{"_id":1,"type":1,"td-op-uid":true}) #不查询条件,只显示_id,type,td-op-uid字段(true和1都行) #通过id查询 db.dalan_test.find({"test_id":"chenwei"}, {_id:0}); #查询test_id结果, 过滤_id字段 db.dalan_test.find({"_id" : ObjectId("64436640873e3385b8bb20ae")}); #通过_id查询 #左边是mongodb查询语句,右边是sql语句。对照着用,挺方便。 db.users.find() select * from users db.users.find({"age" : 27}) select * from users where age = 27 #查询符合的一条,想查询多条需要加{} db.users.find({"username" : "joe", "age" : 27}) select * from users where "username" = "joe" and age = 27 db.users.find({}, {"username" : 1, "email" : 1}) select username, email from users {}表示查询所有 db.users.find({}, {"username" : 1, "_id" : 0}) // no case // 即时加上了列筛选,_id也会返回;必须显式的阻止_id返回 #---------逻辑运算符解释:$lt(<) $lte(<=) $gt(>) $gte(>=) db.users.find({"age" : {"$gte" : 18, "$lte" : 30}}) select * from users where age >=18 and age <= 30 db.users.find({"username" : {"$ne" : "joe"}}) select * from users where username <> "joe" db.users.find({"ticket_no" : {"$in" : [725, 542, 390]}}) select * from users where ticket_no in (725, 542, 390) db.users.find({"ticket_no" : {"$nin" : [725, 542, 390]}}) select * from users where ticket_no not in (725, 542, 390) db.users.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]}) select * form users where ticket_no = 725 or winner = true db.users.find({"id_num" : {"$mod" : [5, 1]}}) select * from users where (id_num mod 5) = 1 db.users.find({"$not": {"age" : 27}}) select * from users where not (age = 27) db.users.find({"username" : {"$in" : [null], "$exists" : true}}) select * from users where username is null // 如果直接通过find({"username" : null})进行查询,那么连带"没有username"的纪录一并筛选出来 #其他查询 db.users.find({"name" : /joey?/i}) // 正则查询,value是符合PCRE的表达式 db.getCollection('表名').find({"_id" : NumberLong("123456123456")}) .......查询id为123456123456的记录(加双引号当做字符串处理) db.food.find({fruit : {$all : ["apple", "banana"]}}) // 对数组的查询, 字段fruit中,既包含"apple",又包含"banana"的纪录 db.food.find({"fruit.2" : "peach"}) // 对数组的查询, 字段fruit中,第3个(从0开始)元素是peach的纪录 db.food.find({"fruit" : {"$size" : 3}}) // 对数组的查询, 查询数组元素个数是3的记录,$size前面无法和其他的操作符复合使用 db.users.findOne(criteria, {"comments" : {"$slice" : 10}}) // 对数组的查询,只返回数组comments中的前十条,还可以{"$slice" : -10}, {"$slice" : [23, 10]}; 分别返回最后10条,和中间10条 db.people.find({"name.first" : "Joe", "name.last" : "Schmoe"}) // 嵌套查询 db.blog.find({"comments" : {"$elemMatch" : {"author" : "joe", "score" : {"$gte" : 5}}}}) // 嵌套查询,仅当嵌套的元素是数组时使用, db.foo.find({"$where" : "this.x + this.y == 10"}) // 复杂的查询,$where当然是非常方便的,但效率低下。对于复杂查询,考虑的顺序应当是 正则 -> MapReduce -> $where db.foo.find({"$where" : "function() { return this.x + this.y == 10; }"}) // $where可以支持javascript函数作为查询条件 db.foo.find().sort({"x" : 1}).limit(1).skip(10); // 返回第(10, 11]条,按"x"进行排序; 三个limit的顺序是任意的,应该尽量避免skip中使用large-number db.name.find({"a": /23$/ })..................db.name.find({"a":{$regex: /23$/ } }).................................这两种正则匹配结果一样 #范围查询 db.user.find( {"name": {"$in": ["张三", "李四", "王五" ] } } ) #查询名字包含"张"字的人 db.user.find( {"name": {"$nin": ["张三", "李四", "王五" ] } } ) #查询名字字段以"张"字开头的人 #模糊查询 db.user.find({"name":/张/}); #查询名字包含"张"字的人: db.user.find({"name":/^张/}); #查询名字字段以"张"字开头的人 db.user.find({"name":/张$/}); #查询名字字段以"张"字结尾的人 #关系运算查询(大于、小于、等于…) db.user.find({"age": {"$gt":19}}).pretty() #查询年龄大于 19 岁的用户 db.user.find({"age": {"$gt":19,"$lt":40}}).pretty() #查询年大于19且小于40 #正则查询 db.AdxLandpage.find({ Name: { $regex: /^第三方落.*chen$/ } }) #匹配Name为”第三方落“开头,”chen“结尾的数据 db.AdxLandpage.find({ Name: { $regex: /^第三方落.*\d$/ }}) #匹配Name为”第三方落“开头,”数字“结尾的数据 db.AdxLandpage.find({ Name: { $regex: /^第三方落[0-9]+$/ }}) #匹配Name为”第三方落“开头,后面跟一位或多位数字
#限制查询
db.集合表.find().limit(2) #查询只显示2条数据
3.插入
> user0={"name":"xiaobai"} > user1={"name":"xiaohuang"} #方式一(推荐): #单条添加,3.2 版本后 > db.user.insertOne({"a": 3}) #批量添加,3.2 版本后 > db.user.insertMany([{"name":"xiaobai"},{"name":"xiaohuang"}]) > db.user.insertMany([user0,user1]) #方式二(不推荐): #单条添加,如果user1没写id,自动生成id,如果有id不能和已有id重复 > db.user.insert({"name":"xiaobai"}) > db.user.insert(user0) #通过变量添加 #批量添加 > db.user.insert([{"name":"xiaobai"},{"name":"xiaohuang"}]) > db.user.insert([user0,user1]) #方式三(会覆盖): > db.user.save({"_id":3,"name":"xiaohei"}) #id等于3,新增name字段并覆盖 #当_id等于29时,新增name字段并赋值test(没有name字段会自动新增),,updateMany是改符合条件所有,updateOne是改一条 db.user.updateMany( { _id: 29 }, { $set: { "name1": "test" } } )
4.更新
#方式一: db.table1.updateOne({"name":"张三"},{$set:{"title":"李四"}}) #根据条件修改一条数据的内容,如出现多条,只修改最高前的数 db.table1.updateMany({"name":"张三"},{$set:{"title":"李四"}}) #根据条件修改所有数据的内容,多条修改 #方式二: db.table1.update()({'name':'张三'},{$set:{'title':'李四'}}) #只会修改先发现的第一条文档。 db.table1.update()({'name':'张三'},{$set:{'title':'李四'}},{multi:true})#如果你要修改多条相同的文档,则需要设置 multi 参数为 true。 db.students.update({name:"张三"},{$set:{age:23}}) #把name为张三的文档的age字段值设置为23 db.students.update({name:"张三"},{$unset:{age:1}}) #把name为张三的文档的age字段删除 db.students.update({name:"张三"},{$inc:{age:5}}) #把name为张三的文档的age字段值 +5
#嵌套更新(更新data下的_id)
db.集合表.update({"data._id":"88966"},{$set:{"data._id":"97492"}})
5.删除
#方式一(推荐): > db.students.deleteOne( { name: "张三" } ) #删除 name 等于 张三 的一个文档 > db.students.deleteMany({ name : "张三" }) #删除 name 等于 张三 的全部文档 > db.students.deleteMany({}) #删除集合下全部文档 #方式二(不推荐): > db.students.remove({name:"张三"},{justOne:true}) #删除 name 等于 张三 的一个文档 > db.students.remove({'name':'张三'}) #删除 name 等于 张三 的全部文档
>db.students.remove({}) #删除students集合下的全部数据 #remove() 方法 并不会真正释放空间,需要继续执行 db.repairDatabase() 来回收磁盘空间。 > db.repairDatabase()
5集合
#查询集合 show collections #展示所有集合 show tables
db.集合.find().pretty() # 查询集合下所有的文档,并整齐显示
#删除集合(表) db.user.info.drop()
#清空集合数据
db.集合.deleteMany({})
#新增集合 #语法:db.createCollection(name, {capped: <boolean>,autoIndexId: <boolean>,size: <数值>,max: <数值>}) #capped:可选,创建固定大小集合,当达到最大值时,它会自动覆盖最早的文档。必须指定 size参数。默认为 false。 #autoIndexId:可选,自动在 _id 字段创建索引。默认为 false。 #size:可选,为固定集合指定一个最大值,以千字节计(KB)。 #max:可选,指定固定集合中包含文档的最大数量。 db.createCollection("test") db.createCollection("test", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
四、python操作mongodb
#!/usr/bin/env python3 #coding: utf-8 import pymongo ###____________________________连接monggodb部分______________________________ ##使用用户名和密码连接 MongoDB client = pymongo.MongoClient('mongodb://admin:admin@192.168.11.151:27017/') ##选择数据库和集合 db = client["dalan_test"] #数据库, 也可以写在一起( db = client["数据库"]["集合"] ) col = db["dalan_test"] #集合(表) ###___________________________信息输出部分___________________________________ print("查看全部数据库名称:",client.list_database_names()) print("查看全部数据库信息:",list(client.list_databases())) print("统计集合中文档数:",col.count()) ###_______________________________插入数据___________________________________ ##插入单条 # mydict = { "name": "John", "address": "Highway 37" } # # 插入数据 # x = col.insert_one(mydict) # # 打印出数据的 ID # print("获取插入成功的_id:",x.inserted_id) #一次插入多条 stu2={'id':'002','name':'lisi','age':15} stu3={'id':'003','name':'wangwu','age':20} result = col.insert_many([stu2,stu3]) print("获取插入后的_id:",result.inserted_ids ) print("好像是是否插入成功:",result.acknowledged) #______________________________查询数据____________________________________ ##获取成list documents = col.find({'name':'test123456'}) #字符串类型 print("直接获取成list:",list(documents)) ##检索集合中所有文档的列表 documents = col.find() for document in documents: print("all查看集合(表)符合条件:",document) ##检索符合特定条件的文档的列表(重要) documents = col.find({'name':'test123456'}) #字符串类型 #documents = col.find({'age': {'$gt': 7}})#整形 for document in documents: print("one查看集合(表)符合条件:",document) ##通过_id查询数据 from bson import ObjectId document_id = ObjectId("6443b8cb14b7609a8c8a5f71") #result = col.find_one({ "_id": document_id }) result = col.find_one({ "_id": document_id },{"_id":0}) #把_id过滤不显示出来 print(result) ##通过_id获取数据(当_id是list时处理方法) cc=[ObjectId('6443c96fabf654b0d8c07b65'), ObjectId('6443c96fabf654b0d8c07b66')] print("通过下标获取",cc[0]) documents = col.find({"_id": {"$in": cc}}) print("通过_id获取文档:",list(documents)
相关连接:
https://blog.csdn.net/cw3225654/article/details/126038286 .................................................................................................mongo基础操作
#嵌套更新