目录

一、数据库二、文档
三、索引
四、聚合

 

一、数据库



show dbs  -- 查看所有数据库
use DATABASE_NAME  -- 如果数据库不存在,则创建数据库,否则切换到指定数据库。
db.dropDatabase()  -- 删除当前数据库
db.COLLECTION_NAME.drop() -- 删除集合



二、文档

1. 插入文档



db.col.insert({  
    title: 'MongoDB Course',
    tags: ['database', 'NoSQL']
})
document = ({  -- 将数据定义为一个变量
    title: 'MongoDB Course',
    tags: ['database', 'NoSQL']
});
db.col.save(document)



2. 更新文档



-- update
db.collection.update(
   <query>,   -- 查询条件,类似sql的where语法
   <update>,  -- 更新的对象,类似sql的set语法
   {
     upsert: <boolean>,  -- 可选,默认是false,表示update的记录不存在时不插入数据,true则为插入,
     multi: <boolean>,   -- 可选,默认是false,只更新找到的第一条记录,true则更新查出来的多条记录。
     writeConcern: <document> -- 可选,抛出异常的级别
   }
)

db.col.update(
    {title: 'MongoDB Course'},
    {$set:{title: 'MongoDB'}}
)
db.col.find().pretty()

-- save 通过传入的文档来替换已有文档
db.col.save({   
    title: 'MongoDB',
    tags: ['database', 'NoSQL']
})

-- update更多例子
db.col.update( { "id" : { $gt : 3 } } , { $set : { "desc" : "OK"} } );  -- 只更新第一条记录
db.col.update( { "id" : { $gt : 3 } } , { $set : { "desc" : "OK"} },false,false ); --只更新第一条记录
db.col.update( { "id" : { $gt : 3 } } , { $set : { "desc" : "OK"} },true, false ); -- 只添加第一条
db.col.update( { "id" : { $gt : 3 } } , { $set : { "desc" : "OK"} },true, true );  --全部添加加进去
db.col.update( { "id" : { $gt : 3 } } , { $set : { "desc" : "OK"} },false,true );  --全部更新



3. 删除文档



db.collection.remove(
   <query>, -- (可选)删除的文档的条件
   {
     justOne: <boolean>,  -- (可选)如果设为 true 或 1,则只删除一个文档。
     writeConcern: <document>  -- (可选)抛出异常的级别。
   }
)
db.col.remove({'title':'MongoDB Course '})



4. 查询文档



db.collection.find(query, projection) -- query:(可选)指定查询条件, projection:(可选)指定返回的键
db.col.find().pretty() -- 以格式化的方式来显示所有文档



(1) MongoDB 与 RDBMS Where 语句比较

mongodb compass 怎么执行sql mongodb sql语法_数组

(2) AND和OR 条件



db.col.find({"by":"tom", "title":"MongoDB"}) -- and
db.col.find({$or:[{"by":"tom"},{"title": "MongoDB"}]}) -- or
db.col.find({"likes":{$gt:50}, $or:[{"by":"tom"},{"title":"MongoDB"}]}) --'where likes>50 AND (by ='tom' OR title='MongoDB')'



(3) 条件操作符



-- $gt >  $gte >=   $lt <  $lte <=   $eq =  $ne != 
db.col.find({likes : {$lte : 150}}) -- where likes <= 150
db.col.find({likes : {$lt :200, $gt : 100}}) -- where likes>100 AND likes<200



(4) $type操作符

MongoDB 中的类型如下:

mongodb compass 怎么执行sql mongodb sql语法_数组_02



db.col.find({"title" : {$type : 2}})  -- 获取 "col" 集合中 title 为 String 的数据



 Limit与Skip方法



limit()  -- 读取指定数量的数据, skip() -- 跳过指定数量的数据
db.col.find({},{"title":1,_id:0}).limit(2)  -- 查询文档中的两条记录
db.col.find({},{"title":1,_id:0}).skip(10).limit(100)  -- 读取从第10条记录后的100条记录



(6) Sort排序方法

  指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列



db.col.find({},{"title":1}).sort({"likes":-1})
db.col.find({"title":"MongoDB"},{"title":1}).sort({"title":1}).skip(2).limit(10)



三、索引

 索引是对数据库表中一列或多列的值进行排序的一种结构,索引通常能够极大的提高查询的效率。对于每个插入的数据,都会自动生成一条唯一的 _id 字段,_id 索引是绝大多数集合默认建立的索引。



db.col.getIndexes() -- 察看索引
db.col.ensureIndex({"title":-1}) -- 按title降序创建索引
db.col.ensureIndex({"title": 1, by: 1}, {background: true}) -- 让创建工作在后台执行
db.col.dropIndexes() -- 删除所有索引
db.col.dropIndex("normal_index") -- 删除指定索引



1. 创建索引

  ensureIndex() 接收可选参数,可选参数列表如下:

 

mongodb compass 怎么执行sql mongodb sql语法_数组_03

2. 查询分析

  MongoDB 查询分析可以确保我们建议的索引是否有效,是查询语句性能分析的重要工具。查询分析常用函数有:explain() 和 hint()。



-- 1. 使用 explain()
db.users.ensureIndex({gender:1,user_name:1})
db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
{
   -- MongoDB中索引存储在B树结构中,所以该查询使用了BtreeCursor类型的游标。没有使用索引的游标类型是BasicCursor。
   -- 可以通过该索引名称查看当前数据库下的system.indexes集合(系统自动创建),获取索引的详细信息。
   "cursor" : "BtreeCursor gender_1_user_name_1",
   "isMultiKey" : false,
   "n" : 1,
   "nscannedObjects" : 0,
   "nscanned" : 1,   -- nscanned/nscannedObjects表明此查询一共扫描了集合中多少个文档,这个数值和返回文档的数量越接近越好。
   "nscannedObjectsAllPlans" : 0,
   "nscannedAllPlans" : 1,
   "scanAndOrder" : false,
   "indexOnly" : true,  -- 字段为 true ,表示我们使用了索引。
   "nYields" : 0,
   "nChunkSkips" : 0,
   "millis" : 0, -- 当前查询所需时间,毫秒数。
   "indexBounds" : {...}  -- 当前查询具体使用的索引。
}

-- 2. 使用 hint()  虽然MongoDB查询优化器一般工作的很不错,但是也可以使用 hint 来强制 MongoDB 使用一个指定的索引。
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain() -- 指定了使用gender和user_name索引字段来查询



3. 覆盖索引查询

  当查询中的所有字段是索引的一部分, MongoDB 只需从RAM中的索引获取数据,比扫描整个文档读取数据要快得多。

  • 所有的查询字段是索引的一部分
  • 所有的查询返回字段在同一个索引中
-- user集合
{ "_id" : 1, "username" : "Amy", "gender" : "F", "score" : 100, "age" : 34 } 
{ "_id" : 2, "username" : "Ram", "gender" : "M", "score" : 90, "age" : 24 }
db.user.ensureIndex({gender:1,username:1})
db.user.find({gender:"M"},{username:1,_id:0}) -- 该查询会被索引覆盖,MongoDB不用去数据库文件中查找
db.user.find({gender:"M"},{username:1}) -- 该查询不会被覆盖,由于我们的索引中不包括 _id字段,而此查询没有排除该字段



4. 高级索引

  当所有索引字段是一个数组或是一个子文档,不能使用覆盖索引查询



-- users集合
{
    "name": "Tom Benzamin"
    "address": {"city": "Los Angeles", "state": "California", "pincode": "123"},  -- 子文档
    "tags": ["music", "cricket", "blogs"]  -- 数组
}

-- 索引数组字段: 在数组中创建索引,需要对数组中的每个字段依次建立索引。因此对数组tags建立索引,会为 music、cricket、blogs三个值建立单独的索引
db.users.ensureIndex({"tags":1})
db.users.find({tags:"cricket"}).explain() -- 执行结果中会显示 "cursor" : "BtreeCursor tags_1" ,表示已经使用了索引

-- 索引子文档字段: 为子文档的三个字段创建索引
db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
db.users.find({"address.city":"Los Angeles"})   
db.users.find({"address.city":"Los Angeles","address.state":"California","address.pincode":"123"})--查询表达式必须遵循指定的索引的顺序



5. 索引限制

(1) 额外开销: 每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。如果你很少对集合进行读取操作,建议不使用索引。
(2) 内存(RAM)限制: 要确保该索引的大小不超过内存(RAM)的限制。如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
(3) 查询限制: 索引不能被以下的查询使用  a. 正则表达式及非操作符,如$nin, $not等     b. 算术运算符,如$mod等     c. $where 子句
(4) 索引键限制:从2.6版本开始,如果现有的索引字段的值超过索引键的限制,MongoDB中不会创建索引。
(5) 最大范围:   a. 集合中索引不能超过64个    b.索引名的长度不能超过128个字符   c.一个复合索引最多可以有31个字段

四、聚合

1. count() 和 distinct()



count --统计文档数量
db.collection.count(<query>) 或者 db.collection.find(<query>).count()
db.user.count({"username":"amy"});  

distinct --对集合中的文档进行去重处理
db.collection.distinct(field,query)
db.user.distinct("username",{“age":{$gt:28}});  -- 用于查询年龄age大于28岁的不同用户名



2. aggregate()

1. 聚合的表达式: 



-- 对每个分组进行计数: select sex, count(*) personCount from col group by sex
db.col.aggregate([{$group: {_id: '$sex', personCount: {$sum:1} }}]) 
  
-- 对每个分组求某一列的总和sum/平均值avg/最大值max/最小值min/第一个值first/最后一个值/last
-- select sex, sum(score) totalScore from col group by sex    
db.col.aggregate([{$group: {_id: '$sex', totalScore: {$sum:'$score'} }}]) 

-- 把每个分组的结果集插入到一个数组中$push/$addToSet(去掉重复的) 
db.mycol.aggregate([{$group: {_id: 'sex', scores: {$push:′score'} }}])



mongodb compass 怎么执行sql mongodb sql语法_数组_04

mongodb compass 怎么执行sql mongodb sql语法_数组_05

2. 管道操作符

  MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
  • $geoNear:输出接近某一地理位置的有序文档。
db.user.aggregate( 
[  
    {$project: {username: 1, score: 1}}, -- 指定输入字段,_id默认是包含的,可添加_id:0去掉
    {$match: {score: {$gt: 70, $lte: 90}}},  
    {$group: {_id: username, count: {$sum: 1}}},
    {$skip : 5}                        
    {$sort : {"username": 1}}
])