乐趣区

关于mongodb:mongodb常用命令4聚合及管道

1. 应用聚合 aggregate 及管道 group 查问反复数据:

首先我的数据库是这样的(存在很多反复数据):

当初应用聚合 aggregate 查问反复数据:

db.ss_tests.aggregate([{$group : {_id : "$id", count : {$sum : 1}}}])

db.ss_tests.aggregate([{$group: { _id: {id: '$id'},count: {$sum: 1}} }])



两条语句是一样的。只不过一个间接输入 value,一个减少了 key 值。

* 语法解释 :应用聚合 aggregate 函数查问,应用索引_id 进行查问, 将 id 雷同的应用管道 $group 将其分为一组,并应用 sum 计算一组的个数,将其赋值给 count,输入

能够看到,我下面语句查问到的反复数据有的有 20 几条之多!

2. 删除反复数据:

办法一,应用聚合解决:

db.ss_tests.aggregate([

  {$group: { _id: '$id',count: {$sum: 1},multiples: {$addToSet: '$_id'}}

  },

  {$match: {count: {$gt: 1}}

  }

]).forEach(function(doc){doc.multiples.shift();

  db.ss_tests.remove({_id: {$in: doc.dups}});

})

* 语法解释:
1. 应用聚合函数对 ss_tests 的 id 雷同的文档(document)进行分组,应用 $sum 进行计算统计 id 雷同的条数,并把条数赋值给 count, 应用 $addToSet 在返回后果中减少 key 为:multiples,value 为:_id 字段(因为聚合分组只会返回参加分组的字段);
演示:
(1)不实用 addToset:
db.ss_tests.aggregate([{$group: { _id: {id: '$id'},count: {$sum: 1}} }])
后果很清晰,没有多余的数据:

{"_id" : { "id" : "3714"}, "count" : 2 }
{"_id" : { "id" : "3542"}, "count" : 1 }
{"_id" : { "id" : "3457"}, "count" : 24 }
{"_id" : { "id" : "3856"}, "count" : 23 }
{"_id" : { "id" : "3261"}, "count" : 4 }
{"_id" : { "id" : "3857"}, "count" : 23 }
{"_id" : { "id" : "3849"}, "count" : 1 }
{"_id" : { "id" : "3771"}, "count" : 23 }
{"_id" : { "id" : "3321"}, "count" : 24 }
{"_id" : { "id" : "2983"}, "count" : 24 }
{"_id" : { "id" : "4141"}, "count" : 23 }
{"_id" : { "id" : "4066"}, "count" : 23 }
{"_id" : { "id" : "3918"}, "count" : 23 }
{"_id" : { "id" : "3770"}, "count" : 23 }
{"_id" : { "id" : "3696"}, "count" : 24 }
{"_id" : { "id" : "3548"}, "count" : 24 }
{"_id" : { "id" : "3519"}, "count" : 24 }
{"_id" : { "id" : "3134"}, "count" : 24 }
{"_id" : { "id" : "3129"}, "count" : 24 }
{"_id" : { "id" : "3054"}, "count" : 24 }

2. 应用 addToset 的范例:
单单是“_id:3054”的就有这么多数据,因为它会把每一个符合条件的“_id”退出对象中

{"_id" : "3054", "count" : 24, "multiples" : [ ObjectId("605a7b8e00c31774b8b1d71f"), ObjectId("605a24b8484104570ceff2ca"), ObjectId("60556465ecc3c2203bcb77b3"), ObjectId("60550d8b1f84370319fddae4"), ObjectId("6054b6b1d47438654aeb098f"), ObjectId("605408f85c26901b6393f2a1"), ObjectId("60545fd3396fea44070dcb12"), ObjectId("605ad26bbe00311786e9a0bb"), ObjectId("6055bb3d0812c740b987fc40"), ObjectId("6057169a70776d3ef59e48ba"), ObjectId("60535aa7c3e533526a0d0e9d"), ObjectId("6053b21d9b938d73a90c1709"), ObjectId("605668e989cf997e62ec36c0"), ObjectId("6058c8c9b9015359d723678f"), ObjectId("60597709e1767e19b9b5b4e8"), ObjectId("605303ca9c9956350d1b5672"), ObjectId("60581b1d9aeace1a78562abe"), ObjectId("605612135f71606091ced0d4"), ObjectId("6056bfc0d8e4b71fd81c4318"), ObjectId("6057c4476b779b7b337cf037"), ObjectId("605871f3735c7a3af6bb659b"), ObjectId("60576d7058a77d5b9ad21916"), ObjectId("605920335ae8b5784cfbe330"), ObjectId("6059cde2206111394daa441e") ] }

2. 再应用 match 匹配大 id 雷同条数大于 1 的 document;
此处演示不必 addToSet 下的后果,比拟容易看:
演示范例:
db.ss_tests.aggregate([{$group: { _id: {id: '$id'},count: {$sum: 1}} }, {$match: {count: {$gt: 1}}}])
后果都是 count 大于 1 的后果:

{"_id" : { "id" : "3714"}, "count" : 24 }
{"_id" : { "id" : "3542"}, "count" : 24 }
{"_id" : { "id" : "3457"}, "count" : 24 }
{"_id" : { "id" : "3856"}, "count" : 23 }
{"_id" : { "id" : "3261"}, "count" : 24 }
{"_id" : { "id" : "3857"}, "count" : 23 }
{"_id" : { "id" : "3849"}, "count" : 23 }
{"_id" : { "id" : "3771"}, "count" : 23 }
{"_id" : { "id" : "3321"}, "count" : 24 }
{"_id" : { "id" : "2983"}, "count" : 24 }
{"_id" : { "id" : "4141"}, "count" : 23 }
{"_id" : { "id" : "4066"}, "count" : 23 }
{"_id" : { "id" : "3918"}, "count" : 23 }
{"_id" : { "id" : "3770"}, "count" : 23 }
{"_id" : { "id" : "3696"}, "count" : 24 }
{"_id" : { "id" : "3548"}, "count" : 24 }
{"_id" : { "id" : "3519"}, "count" : 24 }
{"_id" : { "id" : "3134"}, "count" : 24 }
{"_id" : { "id" : "3129"}, "count" : 24 }
{"_id" : { "id" : "3054"}, "count" : 24 }

3. 应用 js 的 forEach 对返回的 group 组进行遍历,应用 js 办法的 shift 函数将每一个数组的反复的数据的第一个移除。此时再进行删除剩下反复的,因为后面的 shift 办法移除掉每一个反复数据的第一个,所以达到了保留的数据的都没有反复的目标

去除反复数据前,我的 ss_tests 数据汇合中有这么多数据:

应用 forEach 去除数据后:

办法 2:应用 distinct 办法去除反复数据:
此办法有些限度,摘抄官网文档一段话:

NOTE

Results must not be larger than the maximum BSON size. If your results exceed the maximum BSON size, use the aggregation pipeline to retrieve distinct values using the $group operator, as described in Retrieve Distinct Values with the Aggregation Pipeline.

他说最大的数据量不能超过 BSON 的最大容量,即 16MB, 且要传入反复值的字符串,能力删除,此处不做展现,间接放弃。

退出移动版