一、MongoDB的基础操作
1. 创建文档
(1). 在文档中插入一条数据,如果文档不存在会自动创建一个文档。
db.collection.insertOne({name: "a", age: 10})
(2). 创建多个文档
db.collection.insertMany([{name: "a", age: 10}, {name: "b", age: 20}], ordered: false)
# ordered参数用来决定MongoDB是否要按顺序来写入文档,false:表示可以打乱文档的写入顺序,以便优化写入操作的性能。 参数默认值为true
a. 在ordered=true时,一旦遇到错误,操作便会退出,剩余的文档无论正确与否都不会被写入。
b. 在ordered=false时,即使某些文档造成错误,剩余的正确文档仍然会被写入。
(3)创建单个或多个文档
# insert 既可以写入一个单独的文档,也可以写入多个文档
db.collection.insert({name: "a", age: 10}) # 写入一个文档
db.collection.insert([{name: "a", age: 10}, {name: "b", age: 20}]) # 写入两个文档
(4)、insertOne、insertMany、insert的区别
1. insert与insertOne、insertMany返回的结果不一样。
2. insertOne和insertMany命令不支持db.collection.explain()命令;insert支持db.collection.explain()命令。
(5) save命令:db.collection.save()
当save命令处理一个新文档时,它会调用db.collectioin.insert()命令,所以其返回结果与insert一样
2. 读取文档
db.collection.find(<query>, <projection>)
<query>: 定义筛选条件(相当于where)
<projection>:定义投影文档(相当于要返回的字段)
db.thermo_basic_info.find() # 查询所有文档
db.thermo_basic_info.find().pretty() # 更清楚的显示查询出来的所有文档
# 添加筛选条件,两个要同时满足
db.thermo_basic_info.find({CAS_NO: "7727-37-9", Formula: "N2"})
# 复合主键, 查询_id复合主键下type="savings"的文档
db.accounts.find({"_id.type": "savings"})
比较符
# 比较符
db.thermo_basic_info.find({CAS_NO: {"$eq": "7727-37-9"}})
db.thermo_basic_info.find({CAS_NO: {"$in": ["7727-37-9", "12385-13-6"]}})
db.accounts.find({balance: {"$gt": 100, "$lt": 500}}) # 查询balance大于100小于500的文档
逻辑符
# 逻辑符
db.thermo_basic_info.find({CAS_NO: {"$not": {"$eq": "7727-37-9"}}})
# $and
db.thermo_basic_info.find({
"$and": [
{CAS_NO: {"$in": ["7727-37-9", "12385-13-6"]}},
{Formula: "N2"}]
})
# $or
db.thermo_basic_info.find({
"$or": [
{CAS_NO: {"$in": ["7727-37-9", "12385-13-6"]}},
{Formula: "HO2"}]
})
字段操作符
db.accounts.find({"_id.type": {"$exists": true}}) # 读取包含type字段的文档
db.accounts.find({name:{"$type": "null"}}) # 读取name是null的文档
数组操作符
# contact的内容是一个数组
db.accounts.find({"contact": {"$all": ["China", "Beijing"]}}) # 读取contact中既包含China又包含Beijing的文档
运算操作符
db.accounts.find({"name": {"$in": ["/^c/", "/^j/"]}}) # 查询name以c或j开头的文档
db.accounts.find({"name": {"$regex": /LIE/, "$options": "i"}}) # 查询name中包含LIE(不区分大小写的文档) $options=i表示不区分大小写
操作符
比较操作符 | |
$eq | 匹配字段值相等的文档 |
$ne | 匹配字段值不等的文档 |
$gt | 匹配字段值大于查询值的文档 |
$gte | 匹配字段值大于或等于查询值的文档 |
$lt | 匹配字段值小于查询值的文档 |
$lte | 匹配字段值小于或等于查询值的文档 |
$in | 匹配字段值与任一查询值相等的文档 |
$nin | 匹配字段值与任何查询值都不等的文档 |
逻辑操作符 | |
$not | 匹配筛选条件不成立的文档 |
$and | 匹配多个筛选条件全部成立的文档 |
$or | 匹配至少一个筛选条件成立的文档 |
$nor | 匹配多个筛选条件全部不成立的文档 |
字段操作符 | |
$exists | 匹配包含查询字段的文档 |
$type | 匹配字段类符合查询值的文档 |
数组操作符 | |
$all | 匹配数组字段中包含所有查询值的文档 |
$elemMatch | 匹配数组字段中至少存在一个值满足筛选条件的文档 |
运算操作符 | |
$regex | 匹配满足正则表达式的文档 |
2.2. 文档游标
遍历完游标中的所有文档后,或者10分钟后,游标会自动关闭,可以使用.noCursorTimeout()函数来保持游标一直有效, 在这之后需要主动关闭游标,使用close()关闭
myCursor = db.accounts.find().noCursorTimeout() # 游标一直有限
myCursor.close() # 关闭游标
游标函数:
cursor.hasNext():看是否有没有查看的文档
cursor.next():指向下一个文档
cursor.forEach()
cursor.limit(<number>):返回指定数量的文档
cursor.skip(<offset>):跳过指定数量的文档
cursor.count(<applySkipLimit>):<applySkipLimit>默认为false,表示不考虑skip()和limit()的效果
cursor.sort(<document>):<document>定义排序要求, 1=升序,-1=降序
备注:skip()在limit()之前执行,不管我们怎么写;sort()在skip()和limit()之前执行
2.3 文档投影
db.thermo_basic_info.find({}, {CAS_NO: 1, Formula: 1}) # 所有文档只返回CAS_NO,Formula这两个字段, 这样文档id或默认被返回
db.thermo_basic_info.find({}, {CAS_NO: 1, Formula: 1, _id: 0}) # 所有文档只返回CAS_NO,Formula这两个字段, 这样文档id或默认被返回
$silce操作符可以返回数组字段中的部分元素
db.accounts.find({}, {_id: 0, name: 1, contact: {"$slide": 1}}) # 返回contact数组中的第一个元素
3. 更新文档
db.collection.update(<query>, <update>,<options>)
<query>: 定义筛选条件(相当于where)
<update>:更新的内容
<options>:声明了一些更新操作的参数
注意:
1. 文档主键是不可以更改的
2. 在使用<update>文档替换整篇被更新文档时,只有第一篇符合<query>文档筛选条件的文档会被更新
3. 当使用$unset删除数组中的某一个元素时,这个元素不会被删除,只会被赋值为null,而数组的长度不会改变
4. 当使用$rename重命名时,如果新字段在文档中存在,则会先$unset旧字段,再$set新字段
5. $rename旧字段名和新字段名都不可以指向数组元素
6. 当$inc和$mul被更新的字段在文档中不存在时,会自动在文档中加上这个字段,默认为0,然后再做加减乘除操作。
7. 当$min和$max被更新的字段在文档中不存在时,会被添加到文档中
# 更新整篇文档
db.accounts.update({balance: {"$gt": 20, "$lt": 80}}, {"name": "bill", "balance": 50})
# $set, 更新name="jack"的balance,新增info
db.accounts.update({name: "jack"},
{"$set": {
"balance": 3000,
"info": {"branch": "branch1", "dateOpend": new Date("2016-05-18T16:00:00")}
}}
)
# multi更新多个符合条件的文档
db.accounts.update({}, {"$set": {"currency": "USD"}}, {"multi": true})
# upsert: true表示如果update中的筛选条件没有满足条件的文档,则会创建一篇新文档
db.accounts.update({"name": "maggle"}, {"$set": {"balance": 700}}, {"upsert": true})
文档更新操作符
$set | 更新或新增字段 |
$unset | 删除字段 |
$rename | 重命名字段 |
$inc | 加减字段值 |
$mul | 相乘字段值 |
$min | 比较减小字段值 |
$max | 比较增大字段值 |
数组更新操作符 | |
$addToset | 像数组中添加元素 |
$pop | 从数组中移除元素 |
$pull | 从数组中有选择性的移除元素 |
$pullAll | 从数组中有选择性的移除元素 |
$push | 像数组中增加元素。功能比$addToset强大,可与$each、$position、$sort、$slice联合使用 |
4. 删除文档
db.collection.remove(<query>,<options>)
<query>: 定义筛选条件(相当于where)
<options>:声明了一些删除操作的参数
# 删除集合内的所有文档
db.accounts.remove({})
# 删除满足条件的文档,默认删除所有
db.accounts.remove({"balance": 50})
# 只删除满足条件的第一篇文档
db.accounts.remove({"balance": 100}, {"justOne": true})
删除整个集合,包括集合中的所有文档,以及集合的索引
db.collection.drop({writeConcern: <document>})
writeConcern:定义本次集合删除操作的安全写级别
db.accounts.drop()
5. 聚合操作
聚合管道
db.collection.aggregate()