命令
mongodb执行命令时,当一些前置条件不存在时,数据库会自动尝试执行前置条件命令
JS语法,支持运行JS代码
MongoDB可以使用原子操作符或者直接执行javascript代码
CURD参考:https://blog.csdn.net/vbirdbest/article/details/76037827
数组查询,https://cloud.tencent.com/developer/article/1183392
https://www.mongodb.com/docs/manual/tutorial/update-documents-with-aggregation-pipeline/
使用help会列举出mongodb支持操作
help
// 查看所有数据级别的操作
> db.help()
// 查看集合级别的操作
> db.mycoll.help()
// 列举数据库命令
> db.listCommands()
> db.foo.update
function (query, obj, upsert, multi) {
var parsed = this._parseUpdate(query, obj, upsert, multi);
...
}
// 打印语句
> print("hello, mongodb")
hello, mongodb
>
// 执行js脚本
D:\Java\MongoDB\Server\bin>mongo script1.js script2.js
loading file: script1.js
I am script1.js
loading file: script2.js
I am script2.js
// 使用load()函数加载脚本来执行
> load("script1.js")
I am script1.js
true
————————————————
版权声明:本文为CSDN博主「风流 少年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vbirdbest/article/details/76037827
数据库操作
使用数据库,不存在创建
use <dbname>
显示数据库
show dbs
show databases
删除数据库
db.dropDatabse()
集合操作
show collections // 在使用某数据库的情况下使用
// 创建
db.createCollection("colllectionName")
// 获取
db.getCollection("colllectionName")
// 可以使用coll = db.getCollection("colllectionName")获取集合对象,进而使用coll.insert()或coll.save()、coll.find()等操作文档
//coll.save()新版本已经废弃
// 删除
db.collecionName.drop()
文档操作
增
# 集合不存在就会隐式创建
db.<collectionName>.insertMany(
[<document1>, <document2>, ...],
{
writeConern: <document>,
ordered: <boolean>
}
)
# 创建
db.comment.insert({
"articleId":"1000",
"content":"今天天气真好,阳光明媚",
"userId":"100001",
"nickname":"Rose",
"createTime":new Date(),
"likeNum":NumberInt(10),
"state":null
})
db.comment.insertMarry([
{"_id":"1", "userId":"101"},
{"_id":"2", "userId":"102"},
{"_id":"3", "userId":"103"},
{"_id":"4", "userId":"104"}
]);
# 异常处理,回滚
try{
db.comment.insertMarry([
{"_id":"1", "userId":"101"},
{"_id":"2", "userId":"102"},
{"_id":"3", "userId":"103"},
{"_id":"4", "userId":"104"}
]);
}catch (e){
print(e)
}
# js语法????????????????????/
改
db.<collectionName>.update(query, update, options)
db.<collectionName>.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
colllection: <document>,
arrayFilters: [<filterdocument1>, ...],
hint: <document | string>
}
)
# 修改
db.comment.update({_id:"1", {likeNum:NumberInt(1001)}}) # 全局更新,只修改一条数据 # 有点问题
db.comment.update({_id:"1", {$set:{likeNum:NumberInt(1001)}}}) # 局部更新,只修改一条数据
db.comment.update({userId:"1001", {$set:{nickname:"张三"}}},{multi:true}) # 批量更新
db.comment.update({_id:"1", {$inc:{likeNum:NumberInt(1)}}}) # 列值增加,inc修改器
update必须配合操作符进行局部更新,可选insert功能
但是
save兼具insert、update功能
如果文档传入判断文档已存在,例如根据_id判断,就进行全局更新,即覆盖,否则就进行插入
查
# 查询
db.comment.find() # 全表查询
db.comment.find({userId:"1001"}) # 条件查询,以字段作为条件查询,字段值匹配支持正则表达式,相当于模糊查询
db.comment.find({userId:"/^1001$"})
db.comment.find({userId:"1001"}, {userId:1, _id:0}) # 投影查询
db.comment.findOne() # 只查询一个
db.comment.find({userId:"1001"}).skip(2).limit(2) # 分页查询,limit和skip的顺序可以不一致
db.find().sort({userId:-1, likenum:1}) # 排序,1表示升序,-1表示降序
db.comment.find({"likeNum":{$gt:1000}}) # gt lt gte lte ne
db.comment.find({userId:{$in:["101", "102", "103"]}})
db.comment.find({userId:{$nin:["101", "102", "103"]}})
db.comment.find({$and:[{likeNum:{$gte:{NumberInt(500)}}}, {likeNum:{$lte:{NumberInt(1000)}}}]})
db.comment.find({$or:[{likeNum:{$gte:{NumberInt(1000)}}}, {likeNum:{$lte:{NumberInt(500)}}}]})
# 聚合查询
db.comment.count()
db.comment.count({userId:"1001"})
删
// 删除
db.comment.remove({_id:"1"}) # 删除文档
db.comment.remove({}) # 无条件删除数据,批量删除,等同于清空表数据
insert前提就是认为数据不存在
save前提无法确定数据是否存在,但就想保存
update前提就是认为数据已存在
索引操作
MongoDB索引数据结构使用B-Tree
类别:一般索引、复合索引、地理空间索引、文本索引(全文索引)
db.comment.getIndexes()
ns,namespace
key,field,在哪个字段加的索引
v,version
name,索引名称,默认”字段名_排序方式“,如userId_1,对userId升序索引,复合索引列、累加
db.comment.createIndex({userId:1}) # 索引分为升序和降序
# 删除索引,可以通过索引名称或者文档条件删除索引
db.comment.dropIndex({userId:1})
db.comment.dropIndex("userId_1")
db.comment.dropIndexes() # 删除所有,但是_id不会被删除
执行计划
db.comment.find().explain()
全集和扫描
FETCH
COLLSCAN
mongodb查询,没索引全集合扫描,有索引查索引定位数据,如果查询字段直接就是索引字段,直接返回索引值,不在通过定位再读取文档数据返回,有非索引字段再通过定位索引到数据
以 $ 开头,如
$set(更新字段)、
$unset(删除字段)、
$inc(自增或自减)、
$and、$or、$in、$nin、$nor、$exists(用于判断文档中是否包含某字段)、
$push(向数组中尾部添加一个元素)、
$pushAll(将数组中的所有值push)、
$addToSet(向set集合中添加元素)、
$pop(删除数组中的头部或尾部元素),
$pull(删除数组中指定的值)、
$size(根据数组的长度进行筛选)、
$slice(返回数组中部分元素,如前几个、后几个、中间连续几个元素)、
$elemMatch(用于匹配数组中的多个条件)、
$where(自定义筛选条件,效率比较低,需要将bson转为js对象,不能使用索引,可以先使用普通查询过滤掉部分不满足条件的文档,然后再使用where,尽量减少where操作文档的数量过大)
嵌套文档(指有多层的,对应DictField,EnbadDocument???)与数组多重嵌套查询
db.order_for_dw.find({"award.performance_payment":{"$elemMatch":{"user_id":"5cb7ed0dccb7210045535848"}}})
db.order_for_dw.find({"award":{"performance_payment":{"$elemMatch":{"user_id":"5cb7ed0dccb7210045535848"}}}})
EmbeddedDocumentListField 支持在返回的嵌入文档列表上查询 count()、filter()、delete()、create() 等操作。因此,使用 EmbeddedDocumentListField() 而不是 List(EmbeddedDocumentField()) 会更有益。
高级查询必学
https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/
https://www.mongodb.com/docs/manual/crud/
聚合管道,aggregattion pipeline
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理,管道操作是可以重复的
所以MongoDB中的聚合管道和SQL中的聚合不一样,MongoDB中更强大,相当于查询语句
对于查询而言,相当于MongoDB提供了两种方式,一种是find,一种是aggregate,而aggregate能实现聚合
SQL与MongoDB对比
| SQL 操作/函数 | mongodb聚合操作操作符 |
|---|---|
| where | $match |
| group by | $group |
| having | $match |
| select | $project |
| order by | $sort |
| limit | $limit |
| sum() | $sum |
| count() | $sum |
| join | $lookup |
| { $sample: { size: |
|
| $unwind | |
| $push |
//管道阶段stage,array
db.collection.aggregate( [ { <stage> }, ... ] )
aggregate中使用$指定操作符或者使用字段值
{
$group:
{
_id: <expression>, // Group By Expression
<field1>: { <accumulator1> : <expression1> },
...
}
}
_id为必须字段,若置为null或其余任意常量,group将会把所有文档算为一组
一些操作符号只能在聚合管道中使用
$unwind
语法:db.集合名称.aggregate({$unwind:"$字段名称"})
> db.bbb.insert({_id:1,item:'t-shirt', size:['S', 'M', 'L']}))
WriteResult({ "nInserted" : 1 })
> db.bbb.aggregate({$unwind:'$size'})
{ "_id" : 1, "item" : "t-shirt", "size" : "S" }
{ "_id" : 1, "item" : "t-shirt", "size" : "M" }
{ "_id" : 1, "item" : "t-shirt", "size" : "L" }
案例:数据库中有一条数据:{"username":"Bob","tags":["C#","C++","python"]},如何获取该tag列表的长度?
> db.ccc.aggregate({$match:{"username":"Bob"}},{$unwind:"$tags"},{$group:{_id:null, sum:{$sum:1}}})
{ "_id" : null, "sum" : 3 }
注:属性preserveNullAndEmptyArrays值为true表示保留属性值为空的文档,属性值为false表示丢弃属性值为空的文档
> db.ccc.aggregate({$unwind:{path:"$tags", preserveNullAndEmptyArrays:true}})
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "C#" }
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "C++" }
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "python" }
{ "_id" : ObjectId("5fce3d830d2d048bc8fa48de"), "username" : "hhh" }
> db.ccc.aggregate({$unwind:{path:"$tags", preserveNullAndEmptyArrays:false}}) #去掉对应属性值为null的文档
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "C#" }
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "C++" }
{ "_id" : ObjectId("5fce3a720d2d048bc8fa48dd"), "username" : "Bob", "tags" : "python" }
// 数据库连接数
db.serverStatus().connections
//删除数组元素
db.country.insert({“name”:“China”,“province”:[{“name”:“Henan”,“code”:“1001”},{“name”:“Hebei”,“code”:“1002”},{“name”:“Jiangsu”,“code”:“1003”}]});
db.country.update({“name”:“China”},{"$pull":{“province”:{“name”:“Hebei”}}});
删除name为China的p