文章目录
- 一、基础操作
- 一、数据库操作
- 二、集合操作
- 三、文档基本的CRUD
- 1、文档的插入(也可用.save())
- 2、文档的基本查询
- 3、文档的更新(也可用.save())
- 4、删除文档
- 五、文档的更多查询
- 1、统计查询
- 2、分页列表查询
- 3、排序查询
- 4、正则的复杂条件查询
- 5、比较查询
- 6、包含查询
- 7、条件链接查询
- 二、索引
- 一、索引的管理操作
- 1、索引的查看
- 2、索引的创建
- 3、索引的删除
- 二、索引的使用
- 1、执行计划explain
一、基础操作
一、数据库操作
1、启动mongo --host XX --port XX
2、查看现有库 show dbs
3、进入/创建库 use dbName [有则进入,无则创建]
> use Rainbow
switched to db Rainbow
-[mongoDB储存分为两个部分,上部分为内存,下部分为磁盘,当使用use创建的时候,存放的是内存还没有持久化的储存到磁盘的位置(直到该database里面有集合/数据的时候才会被储存到磁盘中),而show出来的是磁盘的位置,所以use创建后直接show是无法直接看到刚刚创建的database]
4、查看当前正在使用的数据库 db
> db
Rainbow
5、删除库 db.dropDatabase() [注:需要先进入该库]
> db.dropDatabase()
{ "ok" : 1 }
二、集合操作
-[注:集合,类似关系型数据库中的表,可以显示的创建,也可以隐式的创建]
1、集合的显式创建db.createCollection(name)
> db.createCollection("myCollection")
{ "ok" : 1 }
2、查看当前库的表
1. > show tables
myCollection
2. > show collections
myCollection
3、删除集合 db.集合名.drop()
> show tables;
Rainbow
class
collection
> db.collection.drop()
true
> show tables;
Rainbow
class
true
三、文档基本的CRUD
-[注:文档(document)的数据结构和JSON基本一样,所有存储在集合中的数据都是BSON格式]
1、文档的插入(也可用.save())
1、单个文档的插入(如当前无此文档将直接创建)
> db.class.save({"name":"Lily","age":"18","sex":"woman"})
WriteResult({ "nInserted" : 1 })
> db.class.insert({"name":"Rainbow","age":"20","sex":"woman"})
WriteResult({ "nInserted" : 1 })
模板:↓
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
----------------------------------------
> db.class.insertOne({"name":"Jesson","age":"21","sex":"man"})
{
"acknowledged" : true,
"insertedId" : ObjectId("5f56f58ac68adc5a2105ef66")
}
2、多个文档的插入(用[]把需要插入的文档括上)
/**
* @document : 要写入的文档
* @writeConcern : 写入策略,默认为1,即要求确认写操作,0 是不要求
* @ordered : 指定是否按顺序写入,默认true,按顺序写入
*/
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
----------------------------------------
> db.class.insertMany([{"name":"Rainbow","age":"20","sex":"woman"},{"name":"Bob","age":"21","sex":"man"},{"name":"Juen","age":"19","sex":"man"}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5f56f552c68adc5a2105ef63"),
ObjectId("5f56f552c68adc5a2105ef64"),
ObjectId("5f56f552c68adc5a2105ef65")
]
}
2、文档的基本查询
1、查看该表中所有的文档db.collectionName.find()
> db.class.find()
{ "_id" : ObjectId("5f56f3b8c68adc5a2105ef61"), "name" : "Rainbow", "age" : "20", "sex" : "woman" }
{ "_id" : ObjectId("5f56f552c68adc5a2105ef64"), "name" : "Bob", "age" : "21", "sex" : "man" }
{ "_id" : ObjectId("5f56f552c68adc5a2105ef65"), "name" : "Juen", "age" : "19", "sex" : "man" }
{ "_id" : ObjectId("5f56f58ac68adc5a2105ef66"), "name" : "Jesson", "age" : "21", "sex" : "man" }
{ "_id" : ObjectId("5f56f5e7c68adc5a2105ef67"), "name" : "Lily", "age" : "18", "sex" : "woman" }
2、根据条件查询
//使用findOne等同于使用limit 1
> db.class.findOne({"age":"21"})
{
"_id" : ObjectId("5f56f552c68adc5a2105ef64"),
"name" : "Bob",
"age" : "21",
"sex" : "man"
}
> db.class.find({"age":"21"})
{ "_id" : ObjectId("5f56f552c68adc5a2105ef64"), "name" : "Bob", "age" : "21", "sex" : "man" }
{ "_id" : ObjectId("5f56f58ac68adc5a2105ef66"), "name" : "Jesson", "age" : "21", "sex" : "man" }
3、只显示部分参数
//第二个{}中1为显示,0为不显示,也可以用true或false表示,如果不使用第二个{}则都显示
> db.class.find({"age":"21"},{name:1,age:1})
{ "_id" : ObjectId("5f56f552c68adc5a2105ef64"), "name" : "Bob", "age" : "21" }
{ "_id" : ObjectId("5f56f58ac68adc5a2105ef66"), "name" : "Jesson", "age" : "21" }
> db.class.find({"age":"21"},{_id:false})
{ "name" : "Bob", "age" : "21", "sex" : "man" }
{ "name" : "Jesson", "age" : "21", "sex" : "man" }
4、try{} catch(){}使用
//因为MongoDB使用insertMany插入的时候哪怕中途有没有插入进去的也是会把其他的插入,导致你无法直观的看出哪条没有插入,所以使用try catch
> try{
db.Rainbow.insertMany([{"name":"Rainbow","age":"20","sex":"woman"},{"name":"Bob","age":"21","sex":"man"},{"name":"Juen","age":"19","sex":"man"}])
}catch(e){
print(e)
}
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5f56faf6c68adc5a2105ef68"),
ObjectId("5f56faf6c68adc5a2105ef69"),
ObjectId("5f56faf6c68adc5a2105ef6a")
]
}
3、文档的更新(也可用.save())
/**
* 模板
* @query : update的查询条件,类似sql update查询内where后面的
* @update : update的对象和一些更新的操作符(如$,$inc(列值增长,自增1)...)等,也可以理解为sql update查询内set后面的
* @upsert : 可选。这个参数的意思是,如果不存在update的记录,是否插入objNew -> true为插入,默认是false不插入
* @multi : 可选。MongoDB默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
* @writeConcern : 可选。跑出异常的级别
*/
db.collectionName.update(
<query>,
<update>,
{
upsert: <boolean>,
multi : <boolean>,
writeConcern : <doucument>
}
)
----------------------------------------------
/**
* 以下语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置multi参数为true。
* 如果不添加$set:,则属于覆盖修改;添加$set:则是只修改相对应的参数'
*/
> db.class.update({"age":"17"},{$set:{"name":"NewLily"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
4、删除文档
//如不添加条件,将会把整个表中数据全部删除
> db.class.remove({"name":"Rainbow"})
WriteResult({ "nRemoved" : 2 })
五、文档的更多查询
1、统计查询
1、统计所有记录数
> db.class.count()
5
2、按条件统计
> db.class.count({"sex":"man"})
3
2、分页列表查询
/**
* 基础语法
* limit : 显示多少条数据
* skip : 跳过的参数,如果数字是3,那么前3个就不要了,默认是0
* limit和skip不分前后
*/
db.collectionName,find().limit(NUMBER).skip(NUMBER)
-------------------------------------------------------
> db.class.find().limit(2)
{ "_id" : ObjectId("5f56f552c68adc5a2105ef64"), "name" : "Bob", "age" : "21", "sex" : "man" }
{ "_id" : ObjectId("5f56f552c68adc5a2105ef65"), "name" : "Juen", "age" : "19", "sex" : "man" }
> db.class.find().limit(2).skip(1)
{ "_id" : ObjectId("5f56f552c68adc5a2105ef65"), "name" : "Juen", "age" : "19", "sex" : "man" }
{ "_id" : ObjectId("5f56f58ac68adc5a2105ef66"), "name" : "Jesson", "age" : "21", "sex" : "man" }
----------------------------------------------------
//需求:每页两个,从第二页开始跳过前两条,接着显示第三、四条
//因为_id的值太过邋遢,所以直接就用命令不显示了
> db.class.find({},{_id:false}).skip(0).limit(2)
{ "name" : "Bob", "age" : "21", "sex" : "man" }
{ "name" : "Juen", "age" : "19", "sex" : "man" }
> db.class.find().skip(2).limit(2)
{ "name" : "Jesson", "age" : "21", "sex" : "man" }
{ "name" : "NewLily", "age" : "17", "sex" : "woman" }
> db.class.find().skip(4).limit(2)
{ "name" : "Rainbow", "age" : "23", "sex" : "woman" }
3、排序查询
注:skip(),limit(),sort()同时出现时,执行的顺序是 sort()>skip()>limit() 和命令编写的顺序无关
/**
* 语法:可多条件查询
* 1为升序
* 2为降序
*/
db.colletionName.find().sort(排序方式)
//根据age排序
> db.class.find({},{_id:false}).sort({"key":1,age:-1})
{ "name" : "Rainbow", "age" : "23", "sex" : "woman" }
{ "name" : "Bob", "age" : "21", "sex" : "man" }
{ "name" : "Jesson", "age" : "21", "sex" : "man" }
{ "name" : "Juen", "age" : "19", "sex" : "man" }
{ "name" : "NewLily", "age" : "17", "sex" : "woman" }
4、正则的复杂条件查询
/**
* 支持js的正则写法
*/
db.collectionName.find({content:正则表达式})
5、比较查询
/**
* $gt >; $lt <; $gte >=; $lte <=; $ne !=;
*/
db.collectionName,find({"field":{$gt:value}})
//查找age>20的数据,因为当初存数据的时候存成string类型了,所以数字需要加双引号"" '
> db.class.find({age : {$gt : "20"}})
{ "name" : "Bob", "age" : "21", "sex" : "man" }
{ "name" : "Jesson", "age" : "21", "sex" : "man" }
{ "name" : "Rainbow", "age" : "23", "sex" : "woman" }
6、包含查询
1、$in的使用
/**
* $in和sql中的in意思一样'
*/
> db.class.find({age:{$in:["19","17"]}},{_id:0})
{ "name" : "Juen", "age" : "19", "sex" : "man" }
{ "name" : "NewLily", "age" : "17", "sex" : "woman" }
7、条件链接查询
1、and的使用
/**
* 语法
* and 和 or语法一样
*/
db.collectionName.find({$and[{},{},{}....]})
//需求:19 <= 年龄 <= 21并且按照年龄升序'
> db.class.find({$and:[{age:{$gte:"19"}},{age:{$lte:"21"}}]},{_id:0}).sort({age:1})
{ "name" : "Juen", "age" : "19", "sex" : "man" }
{ "name" : "Bob", "age" : "21", "sex" : "man" }
{ "name" : "Jesson", "age" : "21", "sex" : "man" }
2、or的使用
//需求:年龄=17或者年龄=23的学生按照age排序'
> db.class.find({$or:[{age:"17"},{age:"23"}]},{_id:0}).sort({age:1})
{ "name" : "NewLily", "age" : "17", "sex" : "woman" }
{ "name" : "Rainbow", "age" : "23", "sex" : "woman" }
二、索引
[1为升序创建索引,-1为降序创建索引]
一、索引的管理操作
1、索引的查看
//返回一个集合中的所有索引的数组 "_id"是默认创建索引
> db.class.getIndexes()
[
{
"v" : 2, //版本号
"key" : { //索引的key 1是升序
"_id" : 1
},
"name" : "_id_", //索引名称
"ns" : "Rainbow.class" //索引所在的表的绝对路径
}
]
2、索引的创建
/**
* 语法
* @keys : 包含索引建和索引类型
* @options : 可选
*/
db.collectionName.createIndex(keys,options)
//对sex字段建立升序索引,命名为"sexIndex"
> db.class.createIndex({"sex":1},{name:"sexIndex"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1, //创建之前已有索引的数量
"numIndexesAfter" : 2, //创建之后已有索引的数量
"ok" : 1
}
//对name和sex创建复合索引并命名为"withIndex"
> db.class.createIndex({"name":1,"sex":-1},{name:"withIndex"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.class.getIndexes() //查询索引,创建成功
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "Rainbow.class"
},
{
"v" : 2,
"key" : {
"sex" : 1
},
"name" : "sexIndex",
"ns" : "Rainbow.class"
},
{
"v" : 2,
"key" : {
"name" : 1,
"sex" : -1
},
"name" : "withIndex",
"ns" : "Rainbow.class"
}
]
3、索引的删除
/**
* 语法
* 删除集合指定索引
*/
db.collectionName.dropIndex("索引名称")
/**
* 语法
* 删除集合所有定索引,但不能删除默认创建的"_id"索引
*/
db.collectionName.dropIndexes()
//删除已有名为"sexIndex"的索引
> db.class.dropIndex("sexIndex")
{ "nIndexesWas" : 2, "ok" : 1 }
二、索引的使用
1、执行计划explain
[分析查询性能.如:查询耗费的时间/是否基于索引查询等]
> db.class.find({"sex":"man"},{_id:false}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "Rainbow.class",
"indexFilterSet" : false,
"parsedQuery" : { //查询语句'
"sex" : {
"$eq" : "man"
}
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : false
},
"inputStage" : {
"stage" : "FETCH",//COLLSCAN是全局扫描,未用上索引
"inputStage" : {
"stage" : "IXSCAN", //查看索引集合
"keyPattern" : {
"sex" : 1
},
"indexName" : "sexIndex", //可用索引的名字
"isMultiKey" : false,
"multiKeyPaths" : {
"sex" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"sex" : [
"[\"man\", \"man\"]"
]
}
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "localhost",
"port" : 27017,
"version" : "4.0.18",
"gitVersion" : "6883bdfb8b8cff32176b1fd176df04da9165fd67"
},
"ok" : 1
}