0-MongoDB常用命令
常用命令
1.增删改查
1.插入
1.插入单个文档
db.collection.insertOne({title:"data",title:"data",...})
db.class_01.insertOne({name:'fqj',set:'male',age:20,english:80,math:70,hobby:['football','basketball','eat','fly']})
2.插入多个文档
db.collection.insertMany([{title:"data",title:"data",...},{title:"data",title:"data",...},...])
db.class_01.insertMany([{name:'cgs',set:'male',age:20,english:80,math:70,hobby:['football','basketball']},{name:'cqs',set:'male',age:20,english:80,math:70,hobby:['football','basketball']},{name:'ty',set:'male',age:20,english:80,math:70,hobby:['football','basketball']},{name:'th',set:'male',age:20,english:80,math:70,hobby:['football','basketball']},{name:'hsy',set:'male',age:20,english:80,math:70,hobby:['football','basketball']}])
2.插入多条嵌套文档
db.class_01.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
3.插入嵌套数组
db.class_01.insert({name: '岛上码农', documents: ['Flutter入门与实战', '高性能MySQL', 'MongoDB专业指北']})
4.插入下级节点为数组
db.class_01.insert({name: '岛上码农', documents: [{name: 'Flutter入门与实战', score: 80}, {name: '高性能MySQL', score: 90}, {name: 'MongoDB专业指北', score: 85}]})
db.class_01.insert({name: '岛上码农', scores: {view: 18800, praise: 290, followers: 105,platform: ['掘金', '公众号']}})
2.查询
1.普通查询
1.查询全部
db.collection.find()
//or
db.collection.find({})
2.MongoDB命令行模式下,格式化find()的返回结果,pretty()
db.class_01.find().pretty()
2.条件查询
1.根据条件查找,只显示查找内容
db.class_01.find({name:'fqj'},{_id:0,name:1})
2.多条件查询,只显示查找内容
db.class_01.find({name:'fqj',math:80},{_id:0,name:1})
3.$gt,大于 >
db.class_01.find({name:'fqj',math:{$gt:70}},{_id:0,name:1})
4.精确匹配嵌套文档,这种写法不仅需要嵌套文档的字段、值相同,字段顺序也得一致
db.class_01.find( { size: { h: 14, w: 21, uom: "cm" } } )
要在嵌入/嵌套文档中的字段上指定查询条件,语法格式如下
"field.nestedField"
5.嵌套字段等于操作
db.class_01.find( { "size.uom": "in" } )
size 字段值是一个文档,找到嵌套文档的 h 字段值等于 in 的所有文档
6.嵌套字段结合单个查询条件操作符
db.class_01.find( { "size.h": { $lt: 15 } } )
size 字段值是一个文档,找到嵌套文档的 h 字段值小于 15 的所有文档
7.多个不同嵌套字段结合 and 操作
db.class_01.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )
三个条件必须同时满足
1.size 字段,嵌套文档的 h 字段值小于 15
2.size 字段,嵌套文档的 uom 字段值等于 in
3.status 字段值等于 D
重点
如果是指定单个字段的时候,可以不需要加 ""(当然,加了也无妨)
例如
db.class_01.find( { status: "D" } )
如果是指定嵌套字段,必须加 "" ,
例如
db.class_01.find( { "size.uom": "in" } )
3.模糊查询
db.test.find({"name" : re.compile("d")})
1
与
db.test.find({"name" : {"$regex" : "d"}})
3.更新
1.删除一个表里的一个字段
db.collection.update({<query>},{$unset:{title:"data"}},false, true)
2.更新单条单个字段
//1.
db.class_01.update({name:'fqj'},{$set:{english:81}})
//2.
db.class_01.updateOne({name:'fqj'},{$set:{english:82}})
3.$upsert:true,没有条件符合更新并插入,默认false不插入
db.class_01.update({name:'yj'},{$set:{sex:'male',age:20,english:80,math:70,hobby:['sing','dance']}},{upsert:true})
4.更新单行多个字段
//1.
db.class_01.updateOne({name:'fqj'},{$set:{english:82,math:80}})
//2.
db.class_01.updateOne({name:'fqj'},{$set:{english:82},$set:{math:80}})
5.更新多行
//1.
db.class_01.updateMany({name:'fqj'},{$set:{english:82,math:80}})
//2.multi:true,更新多行,默认false
db.class_01.update({name:'fqj'},{$set:{english:82,math:80}},{multi:true})
6.更新插入数组
db.class_01.update({name:'fqj'}, {$set:{hobby:['run']}})
7.$push添加值到数组
db.class_01.update({name:'fqj'}, {$push:{hobby:'run'}})
8.$each修饰符添加多个值到数组
db.class_01.update({name:'fqj'}, {$push:{hobby:{$each:['run','fly']}}})
9.$pop运算符-1|1删除数组的第一个或最后一个元素。
db.class_01.update({name:'fqj'},{$pop:{hobby:-1}})
10.$pull运算符从现有数组中删除与指定条件匹配的一个或多个值的所有实例。
db.class_01.update({name:'fqj'},{$pull:{hobby:'run'}})
11.mongoDB 获取系统时间new Date()
db.class_01.updateOne( {_id:ObjectId("632179af4a6528a0680acc41")}, { $set: {modified: new Date()} } )
12.使用$currentDate运算符将字段的值更新为当前日期
db.class_01.updateOne({ "name":"fqj" ,english:{$gt:81}},{$set: { male:"boy" },$currentDate: { lastModified: true }})
mongodb获取时间函数
1.Date() 显示当前的时间
2.new Date() 构建一个格林尼治时间 和Date()相差8小时,+8小时就是系统当前时间, new Date() 必须按照标准的日期格式,日期格式为 yyyy-MM-
ddThh:mm:ssZ,T和Z是单词需要写上
3.ISODate() 也是格林尼治时间,ISODate 可以不按照标准的日期格式
13.mongodb通过ObjectId获得时间
ObjectId("63214a16e1e0d810cb0e3bb1").getTimestamp()
14.嵌套文档更新,更新下级文档的属性
更新下级文档属性时可以直接使用属性访问符"."
db.class_01.updateOne({item:"journal",'size.w':90},{$set:{'size.w': 91}});
db.class_01.updateOne({_id:ObjectId("6322b814ea3037a4cd0626f1")},{$set:{'size.w':90}});
注意,嵌套文档的关键词必须和"field.nestedField"一样,加引号
15.嵌套数组更新,将 MongoDB专业指北改成,‘MongoDB不专业指北’,需要使用到 MongoDB 提供的定位操作符$。定位操作符即表示将对应条件匹配到的数据
db.class_01.update({name: '岛上码农', documents: 'MongoDB专业指北'}, {'$set': {'documents.$': 'MongoDB不专业指北'}});
16.将 documengs 节点的 name 和 score 进行修改。
db.author.update({name: '岛上码农', 'documents.name': 'MongoDB专业指北'},{'$set': {'documents.$.name': 'MongoDB不专业指北', 'documents.$.score':88}});
$定位操作符即在查询条件中找到的数组中的数据元素位置,即表示操作的是该位置的数据
db.author.update({'name': '岛上码农', 'scores.platform': '公众号'},{'$set': {'scores.platform.$':'微信公众号'}});
18.属性增加和移除
1.$push
MongoDB提供了 $push 和 $pull操作指令来增加或移除属性,同时还提供了 $pop 来移除数组的第一个或最后一个值。我们给前一个文档增加一个 homepage 属性。
db.author.update({name: '岛上码农'}, {$push: {homepage: 'https://juejin.cn/user/70787819648695'}});
注意的是,此时插入的是一个名为 homepage 的数组,其中的一个元素是:''https://juejin.cn/user/70787819648695''。如果是增加不是数组的属性,使用$set
指令即可。 可以使用 pull 移除掉匹配的一个属性。
2.$pull
db.author.update(
{name: '岛上码农'},
{$pull: {homepage: 'https://juejin.cn/user/70787819648695'}}
);
3.pop
$pop 操作时使用数字-1和1表示移除首尾的元素,对于下面的数据,移除数组platform里的数据。
数据如下:
{name: '岛上码农',scores : {view: 18800,praise: 290,followers: 105,platform: ['掘金', '公众号', '其他1', '其他2']}}
// 移除第一个元素
db.author.update({name: '岛上码农'}, {$pop: {'scores.platform': -1}});
// 移除最后一个元素
db.author.update({name: '岛上码农'}, {$pop: {'scores.platform': 1}});
2.update命令格式
db.collection.update(query,update,upsert,multi)
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
3.修改集合字段数据
1.存在修改
1.
db.collection.update({'title1':'data1','title2':'data2',...},{$set:{'title1':'data1','title2':'data2',...}})
db.collection.update({'title1':'data1','title2':'data2',...}, {$set:{'title1':'data1'}, $set:{'title2':'data2'},...})
多条件查询时为&&继=即达到全部条件时修改。
2.插入修改(不存在)
db.collection.update({'title1':'data1','title2':'data2',...},{$set:{'title1':'data1','title2':'data2',...}},{upsert:true})
4.删除
query :(可选)删除的文档的条件
1.删除单个文档
db.collection.deleteOne({title: "query"})
删除一条指定数据
db.class_01.deleteOne({_id:ObjectId("632179af4a6528a0680acc41")})
2.删除多个文档
db.collection.deleteMany({title: "query"})
3.删除所有文档
db.collection.deleteMany({})
4.据条件批量删除
例如:num>=10
db.collection.deleteMany({'num':{'$gte':10}})
2.集合操作
1.删除集合
db.collection.drop(collectionName)
2.创建集合
db.createCollection(collectionName)
3.嵌套文档
1.嵌套数组更新
以下面的数据(数据集名称为author)为例:
{name: '岛上码农', documents: ['Flutter入门与实战', '高性能MySQL', 'MongoDB专业指北']}
我们需要将 MongoDB专业指北改成MongoDB不专业指北,就属于修改嵌套的文档数据了。这个时候需要使用到 MongoDB 提供的定位操作符$。定位操作符即表示将对应条件匹配到的数据,如:
db.author.update(
{name: '岛上码农', documents: 'MongoDB专业指北'},
{'$set': {'documents.$': 'MongoDB不专业指北'}}
);
对于下级节点为数组的也是一样。
{
name: '岛上码农',
documents: [
{name: 'Flutter入门与实战', score: 80},
{name: '高性能MySQL', score: 90},
{name: 'MongoDB专业指北', score: 85}
]
}
需要将 documengs 节点的 name 和 score 进行修改。
db.author.update(
{name: '岛上码农', 'documents.name': 'MongoDB专业指北'},
{'$set': {
'documents.$.name': 'MongoDB不专业指北',
'documents.$.score':88}
}
);
$定位操作符即在查询条件中找到的数组中的数据元素位置,即表示操作的是该位置的数据。
2.更新下级文档的属性
更新下级文档属性时可以直接使用属性访问符“.”,例如下面需要更新 praise 增加到291。
{
name: '岛上码农',
scores: {
view: 18800,
praise: 290,
followers: 105
}
}
db.author.update(
{name: '岛上码农'},
{'$set': {'scores.praise': 291}}
);
下级文档若还存在嵌套数组也是类似的操作,如下面的数据,需要将“公众号”换成“微信公众号”:
{
name: '岛上码农',
scores: {
view: 18800,
praise: 290,
followers: 105,
platform: ['掘金', '公众号']
}
}
db.author.update(
{'name': '岛上码农', 'scores.platform': '公众号'},
{'$set': {'scores.platform.$':'微信公众号'}}
);
3.属性增加和移除
MongoDB提供了 $push 和 $pull操作指令来增加或移除属性,同时还提供了 $pop 来移除数组的第一个或最后一个值。我们给前一个文档增加一个 homepage 属性。
db.author.update(
{name: '岛上码农'},
{$push: {homepage: 'https://juejin.cn/user/70787819648695'}}
);
注意的是,此时插入的是一个名为 homepage 的数组,其中的一个元素是:https://juejin.cn/user/70787819648695。如果是增加不是数组的属性,使用$set 指令即可。 可以使用 pull 移除掉匹配的一个属性。
db.author.update(
{name: '岛上码农'},
{$pull: {homepage: 'https://juejin.cn/user/70787819648695'}}
);
$pop 操作时使用数字-1和1表示移除首尾的元素,对于下面的数据,移除数组platform里的数据。
{
name: '岛上码农',
scores : {
view: 18800,
praise: 290,
followers: 105,
platform: ['掘金', '公众号', '其他1', '其他2']
}
}
// 移除第一个元素
db.author.update({name: '岛上码农'}, {$pop: {'scores.platform': -1}});
// 移除最后一个元素
db.author.update({name: '岛上码农'}, {$pop: {'scores.platform': 1}});
4.运算符查询(参考一)
1.关系运算
1.查询年龄为19的人
db.test.find({"age": {"$eq":19}})
2.查询年龄大于19的人
db.test.find({"age": {"$gt":19}})
3.查询年龄大于或等于19的人
db.test.find({"age": {"$gte":19}})
4.查询年龄小于19的人
db.test.find({"age": {"$lt":19}})
5.查询年龄小于或等于19的人
db.test.find({"age": {"$lte":19}})
6.查询年龄不等于19的人
db.test.find({"age": {"$ne":19}})
2.范围查询
1.查询姓名是 “张三”、“李四”、“王五” 的信息
db.test.find( {"name": {"$in": ["张三", "李四", "王五" ]}})
2.查询姓名不是 “张三”、“李四”、“王五” 的信息
db.test.find( {"name": {"$nin": ["张三", "李四", "王五" ]}})
3.逻辑运算查询
1.查询年龄在 19 ~ 25 之间的人
在进行逻辑运算的时候 “and” 操作是最容易,直接使用 “,”分割即可
db.test.find( {"$and": [ {"age": {"$gte" : 19} }, {"age": {"$lte": 25 }}]})
# 等价于
db.test.find({"age": {"$gte": 19, "$lte": 25 }})
2.查询年龄不大于19的人
$not 操作符不能独立使用,必须跟其他操作一起使用(除 $regex)
db.test.find( { "age": { "$not": { "$gt": 19 } } } )
# 等同于
db.test.find( { "age": { "$lte": 19 } } )
3.查询年龄大于25或年龄小于19的人
db.test.find( {"$or": [ {"age": {"$lt" : 19} }, {"age": {"$gt": 25 } } ] })
4.查询年龄在19 ~ 25 之间的人
db.test.find( {"$nor": [ {"age": {"$lt" : 19} }, {"age": {"$gt": 25 } } ] })
4.要素查询
1.$exists
如果 $exists 的值为true,选择存在该字段的文档;若值为 false 则选择不包含该字段的文档。
1.查询不存在 age 字段的文档(所有文档)
db.test.find( { "age": { "$exists" : false } })
1
2.查询 age 字段存在,且值不等于 19 和 25 的文档
db.test.find( { "age": { "$exists" : true, $nin: [ 19, 25 ] } }
1
2.$type
操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果
1.获取 “test” 集合中 name 为 String 的数据
db.test.find({"name" : {$type : 2}})
# 等价于
db.test.find({"name" : {$type : 'string'}})
5.评估查询
1.$expr 使用 $expr 运算符联合多个运算,选出 budget 值大于 spent 值的数据
{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
12345
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
1
2.$jsonSchema
db.createCollection("students", {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "name", "year", "major", "gpa" ],
properties: {
name: {
bsonType: "string",
description: "must be a string and is required"
},
gender: {
bsonType: "string",
description: "must be a string and is not required"
},
year: {
bsonType: "int",
minimum: 2017,
maximum: 3017,
exclusiveMaximum: false,
description: "must be an integer in [ 2017, 3017 ] and is required"
},
major: {
enum: [ "Math", "English", "Computer Science", "History", null ],
description: "can only be one of the enum values and is required"
},
gpa: {
bsonType: [ "double" ],
description: "must be a double and is required"
}
}
}
}
})
参考
https://blog.csdn.net/newbie_907486852/article/details/82528746
3.$mod 查询集合中 amount 键值为 4 的 0 次模数的所有文档
db.inventory.find( { amount: { $mod: [ 4, 0 ] } } )
例如 amount 值等于 16 的文档
{"name":"t1", "amount":16, "tags":[ "school", "book", "bag", "headphone", "appliances" ]}
4.$regex 查询中可以对字符串执行正则匹配
比如刚开始的例子
db.test.find({"name" : re.compile("d")})
对于 options 主要是设置正则的信息查询的标记:
- “i”: 忽略字母大小写
- “m”: 忽多行查找
- “x”: 空白字符串除了被转义的或在字符类中意外的完全被忽略
- “s”:匹配所有的字符(圆点,“.”),包括换行内容
如果是直接使用(javaScript)那么只能够使用 “i” 与 “m”,而 “x” 和 “s” 必须使用 “$regex”
查询name键值以“4”结尾的文档
db.inventory.find( { name: /.4/i } );
# 等价于
db.inventory.find( { name: { $regex: '.4', $options: 'i' } } );
5.$text 匹配文本中含有modeng的BSON
db.test.find( { $text: { $search: "modeng" } } )
6.$where
他可以使用任意的JavaScript作为查询的一部分,包含JavaScript表达式的字符串或者JavaScript函数。
新建fruit集合并插入如下文档:
//插入两条数据
db.fruit.insert({"apple":1, "banana": 4, "peach" : 4})
db.fruit.insert({"apple":3, "banana": 3, "peach" : 4})
比较文档中的两个键的值是否相等.例如查找出banana等于peach键值的文档(4种方法):
//JavaScrip字符串形式
db.fruit.find( { $where: "this.banana == this.peach" } )
db.fruit.find( { $where: "obj.banana == obj.peach" } )
//JavaScript函数形式
db.fruit.find( { $where: function() { return (this.banana == this.peach) } } )
db.fruit.find( { $where: function() { return obj.banana == obj.peach; } } )
查出文档中存在的两个键的值相同的文档,JavaScript函数会遍历集合中的文档:
>db.fruit.find({$where: function () {
for (var current in this) {
for (var other in this) {
if (current != other && this[current] == this[other]) {
return true;
}
}
}
return false;
}});
我们尽量避免使用"Where"査询,因为它们在速度上要比常规査询慢很多。每个文档都要从BSON转换成JavaScript对象,然后通过"where"的表达式来运行;同样还不能利用索引。
6.地理空间
| Name | Description |
|---|---|
| $geoIntersects | 选择与GeoJSON几何体相交的几何体。2dsphere索引支持$geoIntersects |
| $geoWithin | 选择边界GeoJSON几何图形中的几何图形。2dsphere和2d索引支持$geoinfin |
| $near | 返回接近点的地理空间对象。需要地理空间索引。2dsphere和2d索引支持$near |
| $nearSphere | 返回接近球点上的地理空间物体。需要地理空间索引。2dsphere和2d索引支持$nearSphere |
7.阵列
| Name | Description |
|---|---|
| $all | 匹配包含查询中指定的所有元素的数组 |
| $elemMatch | 如果数组字段中的元素与所有指定的$elemMatch条件匹配,则选择文档 |
| $size | 如果数组字段是指定大小,则选择文档 |
1.$all 返回tags数组中含有"appliance", “school”, “book”(必须要是全部包含)的所有bson
db.inventory.find( { tags: { $all: [ "appliance", "school", "book" ] } } )
1
2.$elemMatch 返回tags数组中,所有元素大于等于80小于85的数据
db.scores.find({ tags: { $elemMatch: { $gte: 80, $lt: 85 } } })
1
3.$size 返回tags数组中有两个元素的bson
db.collection.find( { tags: { $size: 2 } } );
7. 按位
| Name | Description |
|---|---|
| $bitsAllClear | 匹配一组位位置的值都为0的数值或二进制值 |
| $bitsAllSet | 匹配一组位位置的值都为1的数值或二进制值 |
| $bitsAnyClear | 匹配数值或二进制值,其中来自一组位位置的任何位的值为0 |
| $bitsAnySet | 匹配数值或二进制值,其中来自一组位位置的任何位的值为1 |
8. 评论(注释)
| Name | Description |
|---|---|
| $comment | 向查询语句添加注释 |
9.投影算符
| Name | Description |
|---|---|
| $ | 在与查询条件匹配的数组中投影第一个元素 |
| $elemMatch | 投影数组中与指定的$elemMatch条件匹配的第一个元素。 |
| $meta | 投影在$text操作期间分配的文档分数 |
| $slice | 限制从数组投影的元素数。支持跳过和限制切片 |
5.查询详解
find()函数
1.指定返回的键
db.[documentName].find ({条件},{键指定})
数据准备:persons.json
1.1 查询出所有数据的指定键(name ,age ,country)
db.persons.find({},{name:1,age:1,country:1,_id:0})
查询条件

经典例题
1.查询所有信息
db.persons.find()
2.查询条件
2.1查询出年龄在25到27岁之间的学生
db.persons.find({age: {$gte:25,$lte:27},{_id:0,age:1})
2.2查询出所有不是韩国籍的学生的数学成绩
db.persons.find({country:{$ne:” Korea”}},{_id:0,m:1})
3.包含或不包含
$in或$nin
2.3查询国籍是中国或美国的学生信息
db.persons.find({country:{$in:[“USA”,“China”]}})
2.4查询国籍不是中国或美国的学生信息
db.persons.find({country:{$nin:[“USA”,“China”]}})
4.OR查询
$or
2.4查询语文成绩大于85或者英语大于90的学生信息
db.persons.find({$or:[{c:{$gte:85}},{e:{$gte:90}}]},{_id:0,c:1,e:1})
5.Null
把中国国籍的学生上增加新的键sex
db.person.update({country:”China”},{$set:{sex:”m”}})
2.5查询出sex 等于 null的学生
db.persons.find({sex:{$in:[null]}},{country:1})
6.正则查询
2.6查询出名字中存在”li”的学生的信息
db.persons.find({name:/li/i},{_id:0,name:1})1
7.$not的使用
$not可以用到任何地方进行取反操作
2.7查询出名字中不存在”li”的学生的信息
db.persons.find({name:{$not:/li/i}},{_id:0,name:1})
$not和$nin的区别是$not可以用在任何地方儿$nin是用到集合上的
8.数组查询$all和index应用
2.8查询喜欢看MONGOD和JS的学生
db.persons.find({books:{$all:[“MONGOBD”,”JS”]}},{books:1,_id:0})
2.9查询第二本书是JAVA的学习信息
db.persons.find({“books.1”:”JAVA”})
9.查询指定长度数组KaTeX parse error: Expected '}', got 'EOF' at end of input: …s.find({books:{size:4}},{_id:0,books:1})`
2.9查询出喜欢的书籍数量大于3本的学生
1.增加字段size
db.persons.update({},{$set:{size:4}},false, true)
2.改变书籍的更新方式,每次增加书籍的时候size增加1
db.persons.update({查询器},{$push:{books:”ORACLE”},$inc:{size:1}})
3.利用$gt查询
db.persons.find({size:{$gt:3}})
2.10利用shell查询出Jim喜欢看的书的数量
var persons = db.persons.find({name:“jim”}) while(persons.hasNext()){
obj = persons.next();
print(obj.books.length) }
10.$slice操作符返回文档中指定数组的内部值
2.11查询出Jim书架中第2~4本书
db.persons.find({name:"jim"},{books:{"$slice":[1,3]}})
2.12查询出最后一本书
db.persons.find({name:"jim"},{books:{"$slice":-1},_id:0,name:1})
11.文档查询
为jim添加学习简历文档 jim.json
2.13查询出在K上过学的学生
1.这个我们用绝对匹配可以完成,但是有些问题(找找问题?顺序?总要带着score?)
db.persons.find({school:{school:"K",score:"A"}},{_id:0,school:1})
2.为了解决顺序的问题我可以用对象”.”的方式定位
db.persons.find({"school.score":"A","school.school":"K"},{_id:0,school:1})
3.这样也问题看例子:
db.persons.find({"school.score":"A","school.school":”J”},{_id:0,school:1})
同样能查出刚才那条数据,原因是score和school会去其他对象对比
4.正确做法单条条件组查询$elemMatch
db.persons.find({school:{$elemMatch:{school:"K",score:"A"}}})
12.$where
12.查询年龄大于22岁,喜欢看C++书,在K学校上过学的学生信息
复杂的查询我们就可以用$where因为他是万能,但是我们要尽量避免少使用它因为他会有性能的代价.

1.mongodb 是NOSQL数据库但是他在文档查询上还是很强大的
2.查询符基本是用到花括号里面的更新符基本是在外面
3.shell是个彻彻底底的JS引擎,但是一些特殊的操作要靠他的各个驱动包来完成
(JAVA,NODE.JS)
Limit,skip,sort的使用
1.Limit返回指定的数据条数
1.1查询出persons文档中前5条数据
db.persons.find({},{_id:0,name:1}).limit(5)
2.Skip返回指定数据的跨度
2.1查询出persons文档中5~10条的数据
db.persons.find({},{_id:0,name:1}).limit(5).skip(5)_
3.Sort返回按照年龄排序的数据[1,-1]
db.persons.find({},{_id:0,name:1,age:1}).sort({age:1})
注意:mongodb的key可以存不同类型的数据排序就也有优先级
最小值-> null->数字 -> 字符串 -> 对象/文档 -> 数组 -> 二进制 -> 对象ID -> 布尔 ->
日期 -> 时间戳 -> 正则 -> 最大值
4.Limit和Skip完成分页
4.1三条数据位一页进行分页
第一页->db.persons.find({},{_id:0,name:1}).limit(3).skip(0)
第二页->db.persons.find({},{_id:0,name:1}).limit(3).skip(3)
4.2 skip有性能问题,没有特殊情况下我们也可以换个思路

对文档进行重新解构设计
每次查询操作的时候前后台传值全要把上次的最后一个文档的日期保存下来
db.persons.find({date:{$gt:日期数值}}).limit(3)
游标
1.游标
利用游标遍历查询数据
var persons = db.persons.find();
while(persons.hasNext()){
obj = persons.next();
print(obj.name)
}

游标到了底部就会释放资源不能再读取了.
2.游标几个销毁条件
1.客户端发来信息叫他销毁
2.游标迭代完毕
3.默认游标超过10分钟没用也会别清除
3.查询快照
快照后就会针对不变的集合进行游标运动了,看看使用方法.
db.persons.find({$query:{name:”Jim”},$snapshot:true})
高级查询选项:
$query
$orderby
$maxsan:integer 最多扫描的文档数
$min:doc 查询开始
$max:doc 查询结束
$hint:doc 使用哪个索引
$explain:boolean 统计
$snapshot:boolean 一致快照
6.使用mongodb增删改查深层嵌套文档
在mongodb中经常遇到这样的数据结构:
{
"_id" : ObjectId("5cd01dfc5d157b5d9bc2750a"),
"results" : [
{
_id:"5cd01dfc5d157b5d9bc27597"
name:"one",
"relation_kpi_draft" : [
{
"parent_id" : null,
"kpi_id" : ObjectId("5cd01dfc5d157b5d9bc2750b"),
"kpi_name" : null,
"is_deleted" : 0,
"_id" : ObjectId("5cd01dfc5d157b5d9bc2750d")
},
{
"parent_id" : null,
"kpi_id" : ObjectId("5cd01dfc5d157b5d9bc2752b"),
"kpi_name" : null,
"is_deleted" : 0,
"_id" : ObjectId("5cd01dfc5d157b5d9bc2751d")
},
]
},
{
_id:"5cd01dfc5d157b5d9bc2757c"
name:"two",
"relation_kpi_draft" : [
{
"parent_id" : null,
"kpi_id" : ObjectId("5cd01dfc5d157b5d9bc2750b"),
"kpi_name" : null,
"is_deleted" : 0,
"_id" : ObjectId("5cd01dfc5d157b5d9bc2750d")
},
{
"parent_id" : null,
"kpi_id" : ObjectId("5cd01dfc5d157b5d9bc2752b"),
"kpi_name" : null,
"is_deleted" : 0,
"_id" : ObjectId("5cd01dfc5d157b5d9bc2751d")
},
]
}
]
}
1.查询
当想查询name=“one"的值时可以直接使用"results.name”:"one"或者results:
{$eleMatch:{name:“one”}}等的方式查询
2.修改
需求1:
将results._id为“5cd01dfc5d157b5d9bc27597”文档中的name字段更改为one-
update
此时我们可以直接使用mongodb中的$占位符,当我们指定条件后,占位符会自动
定位到该字段进行操作
db.集合名称.update(
{"results._id":ObjectId("5cd01dfc5d157b5d9bc27597")},
{$set:{"results.$.name":"one-update"}})
需求2:
将results.id为“5cd01dfc5d157b5d9bc27597”文档中的
relation_kpi_draft数组中的
id为"5cd01dfc5d157b5d9bc2750d"的kpi_name修改为
null-update,
此时我们发现,使用多个$占位符会出现错误无法满足我们的需求,因为目前
mongodb中的占位符只支持一个,社区也没有什么特别好的改进方法,但
mongodb有一个特性,它是文档型数据库,也就是说,可以采用数组+下标的形式
进行操作
栗子:results.$.relation_kpi_draft.0(下标).kpi_name:“one-update”
那么问题又来了,我们如何去获取这个下标呢,当然是要先进行查询了,这个时候建
议大家可以封装一个用于获取这种内嵌文档属性下标方法,提高代码重用度,减少冗
余
当我们查询出该文档并进行条件循环遍历时,便可以得到results.id
_为“5cd01dfc5d157b5d9bc27597”且relation_kpi_draft._id
为“5cd01dfc5d157b5d9bc2750d”的属性下标,得到下标,我们就可以直接精准的
进行更新操作了
db.集合名称.update(
{"results._id":ObjectId("5cd01dfc5d157b5d9bc27597")},
{$set:{results.$.relation_kpi_draft.0.kpi_name:"one-update"}})
这种下标形式的方法是最笨也是最终的办法,所以在设计表结构的时候,尽量不要设
置这种嵌套过深的文档,那样会增加操作的复杂度
3.添加
需求1:
在results.
_id为“5cd01dfc5d157b5d9bc27597”文档中的relation_kpi_draft数组文档再添加一个json
这个很简单,直接使用$占位符就能解决问题
db.集合名称.update(
{"results._id":ObjectId("5cd01dfc5d157b5d9bc27597")},
{$push:{results.$.relation_kpi_draft:
{
"parent_id" : null,
"kpi_id" : ObjectId("5cd01dfc5d157b5d9bc2752t"),
"kpi_name" : null,
"is_deleted" : 0,
"_id" : ObjectId("5cd01dfc5d157b5d9bc2751h")
}
}})
4.删除
分为真删除和假删除,
假删除就是更改一个状态字段,和使用数组下标的方式同理,在这里就不多做阐述。
但真删除,我们使用$pull进行操作,同样是使用占位符,当然,如果嵌套太深,也
只能使用数组下标的形式进行操作
需求:
在results.id为“5cd01dfc5d157b5d9bc27597”文档中的relation_kpi_draft数组文档中
id为“5cd01dfc5d157b5d9bc2750d”的文档删除
db.集合名称.update(
{"results._id":ObjectId("5cd01dfc5d157b5d9bc27597")},
{$pull:{results.$.relation_kpi_draft:
{_id:ObjectId("5cd01dfc5d157b5d9bc2750d")}}})
//删除多个的时候可以使用$in:[]

浙公网安备 33010602011771号