06、MongoDB -- MongoDB 基本用法(删除文档、查询文档、查询运算符)

目录

MongoDB 基本用法

演示前提:

登录单机模式的 mongodb 服务器命令

复制代码
mongod.exe --config "E:\install\mongodb\mongodb-4.2.25\mongod.conf"

登录【admin】数据库的 mongodb 客户端命令

复制代码
mongo mongodb://192.168.0.107:27017/admin -u admin -p 123456

登录【test】数据库的 mongodb 客户端命令

复制代码
mongo mongodb://192.168.0.107:27017/test -u LJHAAA -p 123456

往集合中插入文档、更新文档

删除文档

语法格式

复制代码
db.collection集合名.remove(
   <filter>,     指定删除条件
   <justOne>    是否只删除一条,默认为 false
)

复制代码
db.collection名.remove(
   <filter>,
   {
     justOne: <boolean>,
     writeConcern: <document>,
     collation: <document>
   }
)

两个变体版本:

db.collection.deleteMany() - 删除符合条件的文档,相当于< justOne > 为 false。

db.collection.deleteOne() - 删除符合条件的文档,相当于< justOne > 为 true

1、remove:根据【name】字段删除一条文档

这里有两个文档的【name】都是【火影忍者】,

现在删除 【name】字段为 【火影忍者】的文档,【true】表示指删除一条文档

删除命令:

复制代码
db.books.remove({name:"火影忍者""}, true);

{name:"火影忍者"} 这个是删除条件,相当于 sql 的 where 条件

true 表示只删除一条文档

在图形界面执行删除命令:

删除结果:

成功删除一条【name】为【火影忍者】的数据,还剩一条。

2、deleteOne:根据【name】字段删除一个文档

再随便添加 3 个文档用来测试

复制代码
db.books.insert([{"name":"蜡笔小新",type:"动漫"},{"name":"家庭教师",price:158},{"name":"家庭教师",price:1558,type:"动漫"}])

测试数据:

删除命令:

deleteOne 的删除命令相当于< justOne > 为 true,不需要在命令中指定< justOne >为 true:

复制代码
db.books.deleteOne({name:"蜡笔小新"});

在图形界面执行删除命令:

删除结果:

两条【蜡笔小新】的文档被删除掉一条,只剩下一条。

3、remove:根据【price】删除多条符合条件的文档

删除掉 【price】价格大于 【130】 的文档,现在有两个文档符合匹配条件

命令:

复制代码
db.books.remove({price: {$gt: 130}}, false);

{price: {$gt: 50}} 这个是查询条件,表示匹配 price 的值 大于 50 的文档

false 表示删除多条符合条件的文档

在图形界面执行删除命令:

成功删除多个符合条件的文档

4、deleteMany:根据【price】字段删除多条符合条件的文档

用【deleteMany】删除掉【price】大于【50】的符合条件的多个文档

命令:

复制代码
db.books.deleteMany({price: {$gt: 50}})

在图形界面执行删除命令:

执行结果:

删除多个符合条件的文档成功

上面 writeConcern 与 insert() 方法中的 writeConcern 支持的选项完全相同。

collation 选项支持如下选项值:

复制代码
{
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}

remove() 方法 或 deleteOne、deleteMany() 方法最关键的部分就是 filter 的写法。它的写法也是非常丰富。下面查询文档时再来介绍 filter 的写法。

查询文档

添加测试数据

添加一些文档用来测试

复制代码
db.books.insert([
    {"name":"家庭教师",price:100,type:"动漫"},
    {"name":"蜡笔小新",price:200,type:"动漫"},
    {"name":"火影忍者",price:300,type:"动漫"},
    {"name":"七龙珠",price:400,type:"动漫"},
    {"name":"哆啦A梦",price:500,type:"动漫"},
    {"name":"神奇宝贝",price:600,type:"动漫"},
    {"name":"一人之下",price:700,type:"漫画"},
    {"name":"完美世界",price:800,type:"小说"},
    {"name":"遮天",price:900,type:"小说"},
    {"name":"圣墟",price:1000,type:"小说"}
])

测试数据:

语法格式:

复制代码
db.collection.find( filter ,  projection )

filter 就是查询条件,和前面更新文档、删除文档中的 filter 参数的格式相同。

project 就是一个形如 {字段1: 0, 字段2: 1} 的文档,

其中 0 代表不选出该字段,1 代表选出该字段。

一旦在 find() 方法中定义了 projection,那所有字段默认都不选出

除非使用选项值 1 明确指定要选出该 字段。但_id字段默认选出。

简而言之:指定 projection 参数之后,普通字段默认不选出,但 _id 字段默认选出。

1、查询该集合所有的文档

命令
复制代码
 db.books.find()
查询结果

2、查询价格大于500的文档

命令
复制代码
 db.books.find({price: {$gt: 500}})
查询结果

3、查询价格大于500的,且【type】为【小说】的文档

命令
复制代码
 db.books.find({price: {$gt: 500}, type: "小说"})
命令解释

这里有两个查询条件,且是 and 类型的查询条件

复制代码
db.books.find( 

  {price: {$gt: 500}, type: "小说"}   //一整个花括号表示查询条件文档,查询条件可以看成是一个对象
  
  // price: {$gt: 500}     可以看成是查询条件对象的第 1 个属性
  // type: "小说"          可以看成是查询条件对象的第 2 个属性,两者用逗号隔开

)
查询结果

4、查询价格大于900的,或 type为【漫画】的文档

命令
复制代码
 db.books.find({$or: [{price: {$gt: 900}}, {type: "漫画"}]})
命令解释
复制代码
 db.books.find(
 
   { $or: [ { price: { $gt: 900 } } , { type: "漫画" } ] }
   
   // 表示 or(或)里面有这个   [ { price: { $gt: 900 } } , { type: "漫画" } ] 对象,这个对象必须是一个数组
   
   // or 对象的第 1 个属性值:{ price: { $gt: 900 } } 
   
   // or 对象的第 2 个属性值: { type: "漫画" }


)
查询结果

5、只查询价格大于800的,或 type为【动漫】的name字段、包括_id字段

就是查询来的结果只显示 name 和 id 字段

命令
复制代码
db.books.find({$or: [{price: {$gt: 800}}, {type: "动漫"}]}, {name:1})
命令解释
复制代码
db.books.find(

  { $or: [ { price: { $gt: 800 } }, { type: "动漫" } ] },  { name:1 }
	
  // { $or: [ { price: { $gt: 800 } }, { type: "动漫" } ] }   查询条件
  // { name:1 } 表示查询出来的文档,只显示 【name】这个字段
  // 注意:id 这列是默认显示出来的
  
  // 一旦在 find() 方法中定义了 projection,就是这个【 {name:1} 】,
  // 那所有字段列数据默认都不查询出来,
  // 除非使用选项值 1 明确指定要选出该字段,但_id字段默认选出
  // 例如:可通过  {name:1} 指定只查询 name 这列数据
)

相当于 SQL 命令中的:

复制代码
select id, name from books where price > 800 or type = "动漫" 
查询结果

如图:

一旦在 find() 方法中定义了 projection,就是这个【 {name:1} 】,那所有字段默认都不选出

除非使用选项值 1 明确指定要选出该 字段,但_id字段默认选出。

所以匹配的文档中,只有 name 这个字段被指定查询出来,id是默认查询出来的。

6、只查询价格大于800的,或 type为【动漫】的name字段、不包括_id字段

就是 查出来的文档只显示 name 字段的值

命令
复制代码
db.books.find({$or: [{price: {$gt: 800}}, {type: "动漫"}]}, {name:1, _id:0})
命令解释
复制代码
db.books.find(

  { $or: [ { price: { $gt: 800 } }, { type: "动漫" } ] },  { name:1 , _id:0 }
	
  // { $or: [ { price: { $gt: 800 } }, { type: "动漫" } ] }   查询条件
  //  name:1  value 值为 1,表示查询出 name 这个列
  // _id : 0  value 值为 0,表示这个 id 列不显示出来
  // 注意:id 这列是默认显示出来的,设置 _id:0 ,可显示指定不要让其查询出来。

)

相当于 SQL 命令中的:

复制代码
select  name  from books where price > 800 or type = "动漫" 
查询结果

官方文档查看支持的查询运算符

官方文档4.4版本

官方文档 4.2版本

官网中,Bson type 的用法

查询运算符

范围运算符
复制代码
 $eq   等于
 $gt   大于
 $gte  大于等于
 $in   查询指定值,一个或多个
 $lt   小于
 $lte  小于等于
 $ne   不等于
 $nin:不在xx范围之内。
1、$in:查询 name 为 "家庭教师" 或 "火影忍者 " 的文档

in 后面应该带数组 --》 $in:[ ]

用 in 查询数组里面的多个指定值元素

命令:
复制代码
 db.books.find({name: {$in: ["家庭教师", "火影忍者"]}})
查询结果:

用 in 指定查询 name 为 "家庭教师" 和 " 火影忍者" 的文档

2、$nin:查询 name 不为 "家庭教师" 或 "火影忍者 " 的文档
命令:
复制代码
db.books.find({name: {$nin: ["家庭教师", "火影忍者"]}})
查询结果
逻辑运算符
复制代码
 $and: 该运算符大部分时候可不要,你可直接将多个条件组合成一个filter document。
 
 $not:否, 要求其值必须是文档或正则表达式。

 $nor:异或
 
 $or: 或
3、$not:查询 type 不为【小说】的文档
命令:
复制代码
db.books.find({type: {$not: {$eq: "小说"}}})

// 相当于 type 不等于 "小说"
查询结果:
4、$not:查询 type 不包含【说】的文档(使用正则表达式)

$not 的值需要使用正则表达式

命令:

这个 . 点匹配任意字符

复制代码
db.books.find({type: {$not: /^.+说/}})
查询结果:
元素相关运算符
复制代码
 $exists:要求指定字段存在

 $type:要求指定字段为指定类型。
计算相关运算符
复制代码
$expr	允许在查询中使用聚合表达式
        常用于以下情况:
              在查询中使用聚合算法,如 sum、avg、$max 等。
              对字段进行复杂的比较和条件判断,如大于、小于、等于等。

$jsonSchema	 要求文档必须符合指定JSON Schema(语义约束)

$mod	  Performs a modulo operation on the value of a field and selects documents with a specified result.
          对字段的值执行取模操作,并选择具有指定结果的文档。

 
$regex	   Selects documents where values match a specified regular expression.
           选择值与指定正则表达式匹配的文档。
全文检索相关运算符
复制代码
$text	 执行全文搜索的运算符
 
$where	 允许使用 JavaScript 表达式来执行复杂的查询操作
5、查询必须有name字段、且有price字段,且name字段为string类型、price字段的值为int类型
命令:
复制代码
db.books.find({$jsonSchema: {
     required: [ "name", "price" ],
     properties : {
         name: { bsonType: "string" },
         price: { bsonType: "int"} 
     }
}});

【备注】:可以在这里看字段的类型【Tree View】

查询结果:
6、$regex:查询 type 包含 【漫】的文档
命令
复制代码
db.books.find({type: {$regex: /^.*漫.*$/}})
 
 // $regex 的值应该是正则表达式
 // . 点代表任意字符,* 代表任意字符出现 0 到 多次
查询结果
数组相关的运算符
复制代码
 $all:要求数组包含 all 所指定的多个元素。

这里的 all 相当于组合 and

添加测试数据
复制代码
db.books.insert({name:"一念永恒", prices:[100, 200, 300, 400,500]})   
db.books.insert({name:"仙逆", prices:[400,500,600,700,800]})   
db.books.insert({name:"光阴之外", prices:[600,700,800,900,1000]})   

添加的数据

测试数据区分一下:

7、$all:查询所有 prices 字段中包含 400 和 500 的值
命令:
复制代码
db.books.find({prices: {$all: [400, 500]}})

这里的 all 相当于组合 and,就是且的意思

查询结果
8、$all:查询所有 prices 字段中包含 500 和 600 的值
命令:
复制代码
db.books.find({prices: {$all: [500, 600]}})
查询结果
9、$all:查询所有 prices 字段中包含 500 和 1000 的值
命令:
复制代码
db.books.find({prices: {$all: [500, 1000]}})
查询结果

显然,没有哪一个文档的 prices 数组中,同时包含 500 和 1000 的值

10、$elemMatch:查询所有 prices 中任一元素大于600
命令:
复制代码
db.books.find({prices: {$elemMatch: {$gt: 600}}})

$elemMatch:要求数组中任意一个元素匹配指定的条件

查询结果:
11、$elemMatch:查询所有 prices 中任一元素大于800
命令:
复制代码
db.books.find({prices: {$elemMatch: {$gt: 800}}})  
查询结果:
12、$size:查询 prices 数组 包含 5 个元素
命令:
复制代码
db.books.find({prices: {$size: 5}})

$size:要求指定字段为数组、且包含多少个元素

查询结果:
13、$size:查询 prices 数组 包含 3 个元素
命令:
复制代码
db.books.find({prices: {$size: 3}})

$size:要求指定字段为数组、且包含多少个元素

查询结果:

注意:

因为 $size要求指定字段为数组、且包含多少个元素

这个price 不是数组,所以这个查询是查不到数据的

相关推荐
bing_1582 分钟前
在 Spring Boot 项目中,如何进行高效的数据库 Schema 设计?
数据库·spring boot·后端·数据库schema设计
听雪楼主.19 分钟前
Oracle补丁安装工具opatch更新报错处理
数据库·oracle
不吃元西19 分钟前
对于客户端数据存储方案——SQLite的思考
数据库·sqlite
rgb0f021 分钟前
MySQL视图相关
数据库·mysql·oracle
编程、小哥哥25 分钟前
oracle值sql记录
数据库·sql·oracle
三千花灯31 分钟前
jmeter提取返回值到文件
数据库·jmeter
萧离1951 小时前
超细的Linux安装minio教学
数据库
小吕学编程1 小时前
基于Canal+Spring Boot+Kafka的MySQL数据变更实时监听实战指南
数据库·后端·mysql·spring·kafka
一个小白5551 小时前
Linux,redis群集模式,主从复制,读写分离
linux·运维·数据库·centos
极小狐1 小时前
极狐GitLab 安全文件管理功能介绍
linux·运维·数据库·安全·elasticsearch·gitlab