MongoDB聚合功能浅析

前端技术 2023/09/02 MongoDB

MongoDB数据库功能强大!除了基本的查询功能之外,还提供了强大的聚合功能。这里简单介绍一下count、distinct和group。

1.count:
    

--在空集合中,count返回的数量为0。
  > db.test.count()
  0
  --测试插入一个文档后count的返回值。
  > db.test.insert({\"test\":1})
  > db.test.count()
  1
  > db.test.insert({\"test\":2})
  > db.test.count()
  2
  --count和find一样,也接受条件。从结果可以看出,只有符合条件的文档参与了计算。
  > db.test.count({\"test\":1})
  1

    
2.distinct:
    distinct用来找出给定键的所有不同的值。使用时也必须指定集合和键。
   

--为了便于后面的测试,先清空测试集合。
  > db.test.remove()
  > db.test.count()
  0
  --插入4条测试数据。请留意Age字段。
  > db.test.insert({\"name\":\"Ada\", \"age\":20})
  > db.test.insert({\"name\":\"Fred\", \"age\":35})
  > db.test.insert({\"name\":\"Andy\", \"age\":35})
  > db.test.insert({\"name\":\"Susan\", \"age\":60})
  --distinct命令必须指定集合名称,如test,以及需要区分的字段,如:age。
  --下面的命令将基于test集合中的age字段执行distinct命令。
  > db.runCommand({\"distinct\":\"test\", \"key\":\"age\"})
  {
      \"values\" : [
          20,
          35,
          60
      ],
      \"stats\" : {
          \"n\" : 4,
          \"nscanned\" : 4,
          \"nscannedObjects\" : 4,
          \"timems\" : 0,
          \"cursor\" : \"BasicCursor\"
      },
      \"ok\" : 1
  }

3.group:
    group做的聚合有些复杂。先选定分组所依据的键,此后MongoDB就会将集合依据选定键值的不同分成若干组。然后可以通过聚合每一组内的文档,产生一个结果文档。
   

--这里是准备的测试数据
  > db.test.remove()
  > db.test.insert({\"day\" : \"2012-08-20\", \"time\" : \"2012-08-20 03:20:40\", \"price\" : 4.23})
  > db.test.insert({\"day\" : \"2012-08-21\", \"time\" : \"2012-08-21 11:28:00\", \"price\" : 4.27})
  > db.test.insert({\"day\" : \"2012-08-20\", \"time\" : \"2012-08-20 05:00:00\", \"price\" : 4.10})
  > db.test.insert({\"day\" : \"2012-08-22\", \"time\" : \"2012-08-22 05:26:00\", \"price\" : 4.30})
  > db.test.insert({\"day\" : \"2012-08-21\", \"time\" : \"2012-08-21 08:34:00\", \"price\" : 4.01})
  --这里将用day作为group的分组键,然后取出time键值为最新时间戳的文档,同时也取出该文档的price键值。
  > db.test.group( {
  ... \"key\" : {\"day\":true},      --如果是多个字段,可以为{\"f1\":true,\"f2\":true}
  ... \"initial\" : {\"time\" : \"0\"},    --initial表示$reduce函数参数prev的初始值。每个组都有一份该初始值。
  ... \"$reduce\" : function(doc,prev) { --reduce函数接受两个参数,doc表示正在迭代的当前文档,prev表示累加器文档。
  ...   if (doc.time > prev.time) {
  ...     prev.day = doc.day
  ...     prev.price = doc.price;
  ...     prev.time = doc.time;
  ...   }
  ... } } )
  [
    {
      \"day\" : \"2012-08-20\",
      \"time\" : \"2012-08-20 05:00:00\",
      \"price\" : 4.1
    },
    {
      \"day\" : \"2012-08-21\",
      \"time\" : \"2012-08-21 11:28:00\",
      \"price\" : 4.27
    },
    {
      \"day\" : \"2012-08-22\",
      \"time\" : \"2012-08-22 05:26:00\",
      \"price\" : 4.3
    }
  ]
  --下面的例子是统计每个分组内文档的数量。
  > db.test.group( {
  ... key: { day: true},
  ... initial: {count: 0},
  ... reduce: function(obj,prev){ prev.count++;},
  ... } )
  [
    {
      \"day\" : \"2012-08-20\",
      \"count\" : 2
    },
    {
      \"day\" : \"2012-08-21\",
      \"count\" : 2
    },
    {
      \"day\" : \"2012-08-22\",
      \"count\" : 1
    }
  ]
  --最后一个是通过完成器修改reduce结果的例子。
  > db.test.group( {
  ... key: { day: true},
  ... initial: {count: 0},
  ... reduce: function(obj,prev){ prev.count++;},
  ... finalize: function(out){ out.scaledCount = out.count * 10 } --在结果文档中新增一个键。
  ... } )
  [
    {
      \"day\" : \"2012-08-20\",
      \"count\" : 2,
      \"scaledCount\" : 20
    },
    {
      \"day\" : \"2012-08-21\",
      \"count\" : 2,
      \"scaledCount\" : 20
    },
    {
      \"day\" : \"2012-08-22\",
      \"count\" : 1,
      \"scaledCount\" : 10
    }  
  ]

本文地址:https://www.stayed.cn/item/3427

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。