ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MongoDB - M001第五章 - 索引和聚合管道

2021-12-04 07:00:14  阅读:175  来源: 互联网

标签:sort MongoDB M001 db id 索引 limit year find


聚合框架

  • 聚合框架:只是在MongoDB中查询数据的另一种方式。聚合操作放在 []

  • 聚合框架语法:采用管道的形式,其中阶段按照它们列出的顺序执行。

  • MongoDB Aggregation Framework($group)(计算&重塑数据) > MongoDB Query Language(MQL)(过滤&更新数据)

  • MQL和聚合框架写法区别(Eg: 查找所有将 Wifi 作为便利设施之一的 文档。只在结果游标中包含价格 和 地址)

    • // MQL(MongoDB Query Language:)
      db.listingsAndReviews.find({ "amenities": "Wifi" },
                                 { "price": 1, "address": 1, "_id": 0 }).pretty()
      
      // 聚合框架:
      db.listingsAndReviews.aggregate([
                                        { "$match": { "amenities": "Wifi" } },
                                        { "$project": { "price": 1,
                                                        "address": 1,
                                                        "_id": 0 }}]).pretty()
      
  • 使用聚合而不是MQL查找的原因:

    1. 因为有时候可能用聚合:比如分组操作,以某种方式修改数据。

    2. 并不是总是只需要过滤出正确的文档。

    3. 可以执行除了 查找、投影数据 以外的操作,比如使用聚合进行计算。

    4. 它通过计算、重塑、重组数据的能力 超越了 MQL的 过滤能力。(聚合框架允许我们通过使用\(group、\)sum等阶段来计算和重塑数据。)

  • 管道操作顺序

    • 聚合框架用作管道,管道中的操作顺序很重要
  • 聚合管道数据

    • 数据在管道中是如何处理的?

      • 我们在管道的一端,将数据提供给管道->我们描述了该管道将如何使用聚合阶段处理我们的数据->转换后的数据出现在管道末端。
    • 聚合管道中的数据存在于管道内,本质上不会修改原始数据

聚合框架例子

  • Eg1: 每个_id按照不同类别的price去计数: "total": { "$sum": "$price" }

  • Eg2: 在集合中查找一个文档,并且只 在结果游标中包含地址 字段。

    • db.listingsAndReviews.findOne({ },{ "address": 1, "_id": 0 })
  • Eg3: 仅 投影每个文档的地址 字段值,然后将所有文档分组为每个 address.country 值的一个文档,并为每个组中的每个文档计数一个。

    • db.listingsAndReviews.aggregate([
                                        { "$project": { "address": 1, "_id": 0 }},
                                        { "$group": { "_id": "$address.country",
                                                      "count": { "$sum": 1 } } }
                                      ])
      
  • Eg4: What room types are present in the sample_airbnb.listingsAndReviews collection? 字段:room_type:"xxx"

    • db.listingsAndReviews.aggregate([
                                        { "$project": { "room_type": 1}},
                                        { "$group": { "_id": "$room_type",
                                                      "count": { "$sum": 1 } } }
                                      ])
      
      Answer: db.listingsAndReviews.aggregate([ { "$group": { "_id": "$room_type" } }])
      
      output:
      ...                               
      [
        { _id: 'Entire home/apt', count: 3489 },
        { _id: 'Private room', count: 1983 },
        { _id: 'Shared room', count: 83 }
      ]
      
  • Eg5: 以下哪个命令将返回sample_training.companies集合中5 家历史最悠久的公司的名称和成立年份 ?

    • // 错 
      db.companies.find({}, { "name": 1, "founded_year": 1 }). sort({ "founded_year": 1 }).limit(5)
      // 此命令缺少搜索条件,这意味着将包含空值。排除空值并不总是必要的,因为无论如何将这些类型的值存储在 MongoDB 中并不是最佳实践。所以有很多集合没有空值。然而,这个集合包含空值,我们需要从我们的游标中排除它们,否则在我们排序时它们将是我们的最小值。
      
      // 对
      db.companies.find({ "founded_year": {"$ne":null}},{"name":1,"founded_year": 1}).sort({ "found_year": 1 }).limit(5)
      // 我们首先必须过滤出成立年份不为空的文档,然后投影我们要查找的字段,即名称, 在本例中为founded_year。然后我们按升序对光标进行排序,因此第一个结果将具有found_year字段的最小值。最后,我们将结果限制在游标中的前5 个文档,从而获得 此集合中最古老的5 个公司。
      
      // 对
      db.companies.find({ "founded_year": {"$ne":null}},{"name":1,"founded_year": 1}).limit(5).sort({ "found_year": 1 })
      // 虽然limit()和sort()方法未按正确顺序列出,但 MongoDB 在执行查询时会翻转它们的顺序,提供问题提示正在寻找的结果。
      
      // 错
      db.companies.find({ "name":1,"founded_year": 1}).sort({ "founded_year": 1 }).limit(5)
      // 看起来查询过滤器具有find()命令的投影部分 应该具有的值,并且此命令中没有使用投影。所以这个命令将返回所有 name 等于 1并且created_year也等于1 的公司,不幸的是它错过了问题提示的要求。
      

sort() & limit()

  • sort() & limit() 是游标方法,其他的游标方法有:pretty() , count()

    • 游标方法不适用于:存储在数据库中的数据,它应用于位于游标中的结果集。

    • 这两个一般结合使用,先执行 sort 再执行 limit ,如果``cursor.limit().sort()了,内部执行的还是cursor.sort().limit()` 。

  • sort排序语法:db.COLLECTION_NAME.find().sort({KEY:1,key2:-1});

    • 其中 1 为升序排列,而-1为降序排列
  • Eg1:

    • // 按照人口递增顺序排序,返回第一个文档 = 取人口最少的文档
      db.zips.find().sort({ "pop": 1 }).limit(1)  
      
      // 按照人口递增减序排序,返回第一个文档 = 取人口最多的文档
      db.zips.find().sort({ "pop": -1 }).limit(1) 
      
      // 多个排序
      db.zips.find().sort({ "pop": 1, "city": -1 }) 
      
  • Eg2: sample_training.trips 系列中最年轻的自行车骑手是哪一年出生的?

    • 错:db.trips.find( {"birth year":{"$ne":null} } ).sort({"birth year":-1}).limit(1)  注意第一个花括号要写的
      
      错:db.trips.find({ "birth year": {"$ne":null}},{"birth year": 1}).sort({ "birth year": -1 }).limit(1)
      
      对:  db.trips.find({ "birth year": { "$ne":"" } },
                           { "birth year": 1 }).sort({ "birth year": -1 }).limit(1)
      // 过滤空字符串 而不是null
      

index

  • 是什么

    • 索引是一种特殊的数据结构,以易于遍历的形式存储 集合数据集的一小部分
  • 作用:使查询高效

    • 有很多种方式可以优化查询速度,但是最有效的方式是 添加索引(Indexes)
  • 总结:简单来说,索引是一种 优化查询速度 的 数据结构

  • Eg:

    • db.trips.find({ "birth year": 1989 })
      
      // 创建单个字段索引 single field index = 单一字段
      db.trips.createIndex({ "birth year": 1 })
      
      //如果碰到db.trips.find({ "start station id": 476 }).sort( { "birth year": 1 } ) 这种情况
      
      // 为了使第二次查询更高效,需使用复合索引
      db.trips.createIndex({ "start station id": 1, "birth year": 1 })
      

数据建模

  • 数据建模是什么:一种在文档中组织字段以支持应用程序性能和查询功能的方法。

  • 默认情况下,MongoDB并不强制执行默认的数据组织方式。

  • 那么如何决定用什么结构来存储数据?应该在哪创建子文件?应该在哪用数值数组?在哪一点上,数据应该得到自己的集合?对数据的形状和结构做出这些决定被称为数据建模。 数据建模是一种 在文件中组织字段以支持应用程序 性能和查询功能 的方法。

  • 数据以使用的方式存储。在用MongoDB进行数据建模时,那些被一起访问的数据应该被存储在一起。

  • 当应用程序在变化和发展时,你的数据模型也应该在不断发展。而MongoDB是为快速的数据模型变化和进化而建立的。

Upsert

  • Upsert是什么:更新和插入混合体。

  • 语法:db.collection_name.updateOne( {<query>}, {<update>}, {"upsert":true})

    • 默认情况下 upsertfalse ,如果为 true 则可以执行更新/插入操作。有则更新,无则插入

标签:sort,MongoDB,M001,db,id,索引,limit,year,find
来源: https://www.cnblogs.com/OFSHK/p/15640895.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有