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集合

集合类似于Mysql中的表,由多个文档组成的。但集合不像表那样有字段的限制,集合下面的文档可以是各种各样。比如一个集合下可能有下面多种文档,虽然集合对文档是没有限制的,但是为了数据管理的方便,一般都将相关文档放在一个集合里。
#查询集合
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基础操作

#嵌套更新

posted on 2023-04-22 13:51  chen_2987  阅读(321)  评论(0编辑  收藏  举报

导航