MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)
  53yyhjaWwpCe 2023年11月02日 37 0


 

目录

MongoDB索引Index 


聚合操作

通过聚合操作可以处理多个文档,并返回计算后的结果。

  • 对多个文档进行分组
  • 对分组的文档执行操作并返回单个结果
  • 分析数据变化

 聚合管道

分别由多个阶段来处理文档,每个阶段的输出是下个阶段的输入, 返回的是一组文档的处理结果,例如,total、average、 maxmium、minimium。

 插入下列数据,供聚合操作用

db.orders.insertMany( [
   { _id: 0, name: "Pepperoni", size: "small",price: 19,
     quantity: 10, date: ISODate( "2030-03-13T08:14:30Z" ) },
   { _id: 1, name: "Pepperoni", size: "medium",price: 20,
     quantity: 20, date : ISODate( "2030-03-13T09:13:24Z" ) },
   { _id: 2, name: "Pepperoni", size: "large",price: 21,
     quantity: 30, date : ISODate( "2030-03-17T09:22:12Z" ) },
   { _id: 3, name: "Cheese", size: "small",price: 12,
     quantity: 15, date : ISODate( "2030-03-13T11:21:39.736Z" ) },{ _id: 4, name: "Cheese",
size: "medium", price: 13,
    quantity:50, date : ISODate( "2031-01-12T21:23:13.331Z" ) }, { _id: 5, name:"Cheese", size: "large", price: 14,
     quantity: 10, date : ISODate( "2031-01-12T05:08:13Z" ) },
   { _id: 6, name: "Vegan", size: "small",price: 17,
     quantity: 10, date : ISODate( "2030-01-13T05:08:13Z" ) },
   { _id: 7, name: "Vegan", size: "medium",price: 18,
     quantity: 10, date : ISODate( "2030-01-13T05:10:13Z" ) }
] )

计算尺寸为medium的订单中,每种类型的订单数量

db.orders.aggregate( [
   // Stage 1: 匹配size:"medium"的文档
   {
      $match: { size: "medium" }
   },
   // Stage 2: 根据name统计过滤后的文档,并把"quantity"值相加
   {
      $group: { _id: "$name", totalQuantity: {$sum: "$quantity" } }
   }
] )

输出结果:

[
   { _id: 'Cheese', totalQuantity: 50 },
   { _id: 'Vegan', totalQuantity: 10 },
   { _id: 'Pepperoni', totalQuantity: 20 }
]

更复杂的例子:

db.orders.aggregate( [
   // Stage 1: 根据日期范围过滤
   {
      $match:
     {
         "date": { $gte: new ISODate( "2030-01-01" ), $lt: new ISODate( "2030-01-30" ) }
     }
   },
   // Stage 2: 对过滤后文档以日期为条件进行分组并计算
   {
      $group:
     {
         _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
         totalOrderValue: { $sum: { $multiply:[ "$price", "$quantity" ] } },
         averageOrderQuantity: { $avg:"$quantity" }
     }
   },
   // Stage 3: 按照订单价值倒序排列文档
   {
      $sort: { totalOrderValue: -1 }
   }
 ] )

计算结果:

{ "_id" : "2030-01-13", "totalOrderValue" : 350, "averageOrderQuantity" : 10 }

统计集合中文档数量

db.collection.count()

根据指定的字段进行过滤,去掉重复的文档

db.collection.distinct()

聚合管道顺序优化

聚合管道在执行的过程中有一个优化的阶段,以提高性能。

$addFields: {
    maxTime: { $max: "$times" },
    minTime: { $min: "$times" }
} },
{ $project: {
    _id: 1, name: 1, times: 1, maxTime: 1,minTime: 1,
    avgTime: { $avg: ["$maxTime", "$minTime"] }
} },
{ $match: {
    name: "Joe Schmoe",
    maxTime: { $lt: 20 },
    minTime: { $gt: 5 },
    avgTime: { $gt: 7 }
} }

优化思路:优化器把$match阶段分成了4个独立的过滤器,尽可能 把过滤器放在$project操作前面,优化后的聚合管道如下:

{ $match: { name: "Joe Schmoe" } },
{ $addFields: {
    maxTime: { $max: "$times" },
    minTime: { $min: "$times" }
} },
{ $match: { maxTime: { $lt: 20 }, minTime: { $gt: 5 } } },
{ $project: {
    _id: 1, name: 1, times: 1, maxTime: 1, minTime: 1,
    avgTime: { $avg: ["$maxTime", "$minTime"] }
} },
{ $match: { avgTime: { $gt: 7 } } }

再例如:

{ $sort: { age : -1 } },
{ $match: { status: 'A' } }

优化后:

{ $match: { status: 'A' } },
{ $sort: { age : -1 } }

限制事项

  • 返回结果集不能超过16M字节
  • 单个管道中的stage数量不能超过1000个(MongoDB 5.0)

实时效果反馈

1.下列聚合操作命令中有错的是哪个? 

A $sum、$avg、$unset

B $min 、$push、$first

C $last、$group、$project

D $match、$limit、$max

MongoDB索引Index 

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_数据

索引概述

索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指 向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当 于图书的目录,可以根据目录中的页码快速找到所需的内容。索引目标是提高数据库的查询效率,没有索引的话,查询会进行全表扫描(scan every document in a collection),数据量大时严重降低 了查询效率。默认情况下Mongo在一个集(collection)创建时, 自动地对集合的_id创建了唯一索引。 

 索引类型

单键索引

MongoDB默认所有的集合在_id字段上有一个索引。 下图是一个在score字段上建立的升序/降序索引示意图。

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_mongodb_02

创建一个名为records的集合,并插入下面的数据

{
  "_id": ObjectId("180c06a4ad577233f97tf825"),
  "score": 356,
  "location": { province: "Hebei", city: "Tangshan" }
}

 创建索引,1代表升序,-1代表降序

db.records.createIndex( { score: 1 } )

在内嵌字段上建立索引

db.records.createIndex( { "location.province": 1 } )

在内嵌文档上建立索引

db.records.createIndex( { location: 1 } )

复合索引

复合索引是指单个索引结构指向多个字段,下图展示了在两个字段 上建立索引

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_数据_03

使用下面的数据来创建一个复合索引

{
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}

 在item和stock字段上建立升序索引

db.products.createIndex( { "item": 1, "stock": 1 } )

复习:

文件上传_SpringBoot基于FastDFS实现

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_字段_04

 引入Thymeleaf视图解析器

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency> 
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

下载wangEditor富文本编辑器

为何选择 wangEditor

简洁、轻量级、文档齐全

万星项目 Github Star 1w+

npm 周下载量 1w+

CDN 月下载量百万+(来自 jsdelivr)

QQ 群及时答疑

开源团队维护,非个人单兵作战

 

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_数据库_05

 编写index页面

<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>wangEditor demo</title>
</head>
<body>
<div id="div1">
    <p>欢迎使用 <b>wangEditor</b> 富文本编辑器
</p>
</div>
<script type="text/javascript" th:src="@{wangEditor.min.js}"
src="../static/wangEditor.min.js"></script>
<script type="text/javascript">
    const E = window.wangEditor
    const editor = new E('#div1')
    //设置文件上传的参数名称
    editor.config.uploadFileName = 'files'
    // 配置 server 接口地址
    editor.config.uploadImgServer = '/upload/uploadMoreImage.do'
    // 2M
    editor.config.uploadImgMaxSize = 2 *1024 * 1024
    editor.config.uploadImgAccept = ['jpg','jpeg', 'png', 'gif', 'bmp', 'webp']
    // 一次最多上传 5 个图片
    editor.config.uploadImgMaxLength = 5
    editor.create()
</script>
</body>
</html>

编写Controller接口

@RestController
@RequestMapping("/upload")
public class UoloadToFastDFSController {
    //fastdfs存储节点的客户端对象
    @Autowired
    private FastFileStorageClient fastFileStorageClient;
    @GetMapping("/upload")
    public void uploadMoreImage(MultipartFile[] files){
        //判断是否上传图片
        if(files != null && files.length != 0 ){
            //遍历上传图片
            for (MultipartFile multipartFile : files) {
                //获取上传文件名
                String filename = multipartFile.getOriginalFilename();
                //获取最后一个“.”的下标,并获取从这个下标的下一个下标开始后的字符作为文件后缀
                String fileSuffix = filename.substring(filename.lastIndexOf(".")+ 1);
                StorePath storePath = null;
                try {
                    //上传文件
                    storePath = fastFileStorageClient.uploadFile(multipartFile.getInputStream(),multipartFile.getSize(), fileSuffix, null);
               } catch (IOException e) {
                    e.printStackTrace();
               }
                //打印返回的文件在存储节点的唯一标识
          System.out.println(storePath.getFullPath());
          }
       }
   }
}

FastDFS集成Nginx

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_mongodb_06

 Nginx服务器是一个高性能的web服务器与反向代理服务器。

FastDFS集成Nginx的2个原因

1 为分布式文件系统提供Http服务支持

通过Nginx的web服务代理访问分布式文件系统的存储节点,从而实 现通过http请求访问存储节点资源。

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_mongodb_07

注意: src 属性值图像文件的 URL。也就是引用该图像的文件的的绝对路径或相对路径。 

 1 解决复制延迟问题

由于FastDFS的同卷的存储节点之间需要同步,当文件尚未同步完成时,访问请求到达改节点,获取的数据将是未同步完的不完整数 据,即为复制延迟问题。通过Nginx检测请求的存储节点的数据, 若该存储节点的数据尚未同步完成,则将请求转发至数据的原存储节点,从而解决复制延迟问题。

MongoDB【MongoDB索引Index (索引概述、索引类型、复合索引、)】(三)-全面详解(学习总结---从入门到深化)_数据库_08

实时学习反馈

1.FastDFS集成Nginx主要目的正确的是____。

A 为分布式文件系统提供Http服务支持

B 解决复制延迟问题

C 以上都是正确 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jnZtF7Co41Wg   2023年12月09日   27   0   0 客户端服务端数据
  Yoru5qB4TSKM   2023年12月10日   38   0   0 服务器重启IP