一,问题描述

【使用 unwind 操作符 “解包” Document 里面的Array中的每个元素,然后使用 group 分组统计,最后使用 sort 对分组结果排序】

从 images.json 文件中导入数据到MongoDB服务器

mongoimport --drop -d test -c images images.json

其中Document的示例如下:

> db.images.find()
{ "_id" : 3, "height" : 480, "width" : 640, "tags" : [ "kittens", "travel" ] }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : [ "cats", "sunrises", "kittens", "travel", "vacation", "work" ] }
{ "_id" : 0, "height" : 480, "width" : 640, "tags" : [ "dogs", "work" ] }
{ "_id" : 6, "height" : 480, "width" : 640, "tags" : [ "work" ] }
{ "_id" : 4, "height" : 480, "width" : 640, "tags" : [ "dogs", "sunrises", "kittens", "travel" ] }
{ "_id" : 5, "height" : 480, "width" : 640, "tags" : [ "dogs", "cats", "sunrises", "kittens", "work" ] }
{ "_id" : 7, "height" : 480, "width" : 640, "tags" : [ "dogs", "sunrises" ] }
{ "_id" : 8, "height" : 480, "width" : 640, "tags" : [ "dogs", "cats", "sunrises", "kittens", "travel" ] }

现在要统计: 所有Document中的 tags 数组里面的每个元素 出现的次数。即:"kittens"出现了多少次?"travel"出现了多少次?"dogs"出现了多少次?……

二,实现步骤

使用MongoDB的Aggregate操作进行实现

①使用 unwind 分解 tags 数组,得到的结果如下:

> db.images.aggregate(
... [
... {$unwind:"$tags"}
... ])
{ "_id" : 3, "height" : 480, "width" : 640, "tags" : "kittens" }
{ "_id" : 3, "height" : 480, "width" : 640, "tags" : "travel" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "cats" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "sunrises" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "kittens" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "travel" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "vacation" }
{ "_id" : 1, "height" : 480, "width" : 640, "tags" : "work" }
{ "_id" : 0, "height" : 480, "width" : 640, "tags" : "dogs" }
{ "_id" : 0, "height" : 480, "width" : 640, "tags" : "work" }
{ "_id" : 6, "height" : 480, "width" : 640, "tags" : "work" }
{ "_id" : 4, "height" : 480, "width" : 640, "tags" : "dogs" }
{ "_id" : 4, "height" : 480, "width" : 640, "tags" : "sunrises" }
.....
.....

②将分解后的每个 tag 进行 group 操作

对于group操作而言,_id 指定了 分组 的字段(对哪个字段进行 group by 操作),分组操作之后生成的结果由 num_of_tag 字段标识

> db.images.aggregate(
... [
... {$unwind:"$tags"},
... {$group:{_id:"$tags",num_of_tag:{$sum:1}}}
... ]
... )
{ "_id" : "dogs", "num_of_tag" : 49921 }
{ "_id" : "work", "num_of_tag" : 50070 }
{ "_id" : "vacation", "num_of_tag" : 50036 }
{ "_id" : "travel", "num_of_tag" : 49977 }
{ "_id" : "kittens", "num_of_tag" : 49932 }
{ "_id" : "sunrises", "num_of_tag" : 49887 }
{ "_id" : "cats", "num_of_tag" : 49772 }

③使用 project 去掉不感兴趣的 _id 字段(其实这里是将 _id 字段名 替换为 tags 字段名)(这一步可忽略)

project操作,_id:0 表示去掉_id 字段;tags:"$_id",将 _id 字段值 使用tags 字段标识;num_of_tag:1 保留 num_of_tag 字段

> db.images.aggregate( [ {$unwind:"$tags"},{$group:{_id:"$tags",num_of_tag:{$sum:1}}},{$project:{_id:0,tags:"$_id",num_of_tag:1}} ])
{ "num_of_tag" : 49921, "tags" : "dogs" }
{ "num_of_tag" : 50070, "tags" : "work" }
{ "num_of_tag" : 50036, "tags" : "vacation" }
{ "num_of_tag" : 49977, "tags" : "travel" }
{ "num_of_tag" : 49932, "tags" : "kittens" }
{ "num_of_tag" : 49887, "tags" : "sunrises" }
{ "num_of_tag" : 49772, "tags" : "cats" }

④使用 sort 对 num_of_tag 字段排序

> db.images.aggregate( [ {$unwind:"$tags"},{$group:{_id:"$tags",num_of_tag:{$sum:1}}},{$project:{_id:0,tags:"$_id",num_of_tag:1}},{$sort:{num_of_tag:-1}} ])
{ "num_of_tag" : 50070, "tags" : "work" }
{ "num_of_tag" : 50036, "tags" : "vacation" }
{ "num_of_tag" : 49977, "tags" : "travel" }
{ "num_of_tag" : 49932, "tags" : "kittens" }
{ "num_of_tag" : 49921, "tags" : "dogs" }
{ "num_of_tag" : 49887, "tags" : "sunrises" }
{ "num_of_tag" : 49772, "tags" : "cats" }

三,总结

本文是MongoDB University M101课程 For Java Developers中的一次作业。结合Google搜索和MongoDB的官方文档,很容易就能实现MongoDB的各种组合查询。

相关MongoDB文章:

MongoDB 更新数组中的元素

MongoDB 组合多个条件查询($and、$in、$gte、$lte)

原文:http://www.cnblogs.com/hapjin/p/7944404.html

MongoDB统计文档(Document)的数组(Array)中的各个元素出现的次数的更多相关文章

  1. iOS 判断数组array中是否包含元素a,取出a在array中的下标+数组方法详解

    目前找到来4个解决办法,第三个尤为简单方便 NSArray * arr = @["]; //是否包含 "]) { NSInteger index = [arr indexOfObj ...

  2. mongodb的基本操作与插入文档(document)

    一.mongodb的基本操作: 1.查看mongodb当前所有的databases : show dbs 2.选择数据库(database) : use databaseName(该数据库不存在则会自 ...

  3. Mongodb嵌套文档的改动-利用数组改动器更新数据

    初学mongodb的可能和我一样有个疑问.mongodb是文档型的,那么假设一个文档嵌套另外一个文档,假设对这个嵌套文档进行增删改查呢. 就像例如以下这样:.怎样对auther里面的name进行增删改 ...

  4. mongodb查询文档

    说到查询,我们一般就想起了关系型数据库的查询了,比如:order by(排序).limit(分页).范围查询(大于某个值,小于某个值..,in查询,on查询,like查询等待很多),同样mongodb ...

  5. Javascript学习8 - 脚本化文档(Document对象)

    原文:Javascript学习8 - 脚本化文档(Document对象) 每个Web浏览器窗口(或帧)显示一个HTML文档,表示这个窗口的Window对象有一个document属性,它引用了一个Doc ...

  6. MongoDB数据库文档操作

    前面的话 本文将详细介绍MongoDB数据库关于文档的增删改查 数据类型 在介绍文档操作之前,首先要了解MongoDB的数据类型 MongoDB支持许多数据类型,包括 1.字符串 - 这是用于存储数据 ...

  7. MongoDB插入文档

    db.collection.insertOne() 插入单个文档.db.collection.insertMany() 插入多个文档.db.collection.insert() 插入单/多个文档.  ...

  8. PyRevit开发第一步:获取Revit文档Document

    1.安装PythonShell插件 PythonShell 2018 插件下载 交流QQ群: 17075104 新建项目后,运行功能Python Shell, 在弹出的窗口中复制或输入以下引用代码模块 ...

  9. 【ElasticSearch】:索引Index、文档Document、字段Field

    因为从ElasticSearch6.X开始,官方准备废弃Type了.对应数据库,对ElasticSearch的理解如下: ElasticSearch 索引Index 文档Document 字段Fiel ...

随机推荐

  1. CS academy Binary Flips(dp)

    开学啦,没啥时间写博客..过几天就能又停课啦qwq 做点中等 \(dp\) 题来找找 noip 的感觉 233 题意 原题戳这里. 给你一个 \(n \times m\) 的矩阵 \(A\) ,一开始 ...

  2. Scout YYF I POJ - 3744(概率dp)

    Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into th ...

  3. LOJ#6278. 数列分块入门 2

    在一个区间上进行操作,一种操作是某个小区间都加上c,另一个查找这个区间内大于c*c的数 我们可以另外开一个数组在保存a中的每个分块内的相对值,然后每次对a加值,并把a的值赋给b,不同的是b内的各个分块 ...

  4. Gym-100451B:Double Towers of Hanoi

    题目链接 题目大意:把汉诺双塔按指定顺序排好的最少步数 我写这题写了很久...终于发现不dp不行 把一个双重塔从一根桩柱移动到另一根桩柱需要移动多少次? 最佳策略是移动一个双重 (n-1) 塔,接着移 ...

  5. Libre OJ 144、145 (DFS序)

    部分参考自博客:https://blog.csdn.net/hpu2022/article/details/81910490 在许多问题中,由于树结构复杂通常会导致问题很棘手,因为其实非线性结构,操作 ...

  6. jsp model1

    一.model1(纯jsp技术): 1.dao:data access object,数据访问对象,即专门对数据库进行操作的类,一般说dao不含业务逻辑. 2.当进行跳转时候,需要用servlet来实 ...

  7. Windows系统服务管理

    1.用SC命令管理: 启动redis服务: C:\Users\Administrator>sc start redis 停止redis服务: C:\Users\Administrator> ...

  8. A1014. Waiting in Line

    Suppose a bank has N windows open for service. There is a yellow line in front of the windows which ...

  9. 解决在vue中axios请求超时的问题

    查看更多精彩内容请访问我的新博客:https://www.cssge.com/ 自从使用Vue2之后,就使用官方推荐的axios的插件来调用API,在使用过程中,如果服务器或者网络不稳定掉包了, 你们 ...

  10. sublime中编辑服务器上的文件

    背景:公司项目需要进行构建编译,在服务器上速度比较快,所以需要将sublime和linux中的文件相关联. 参考资料:http://zyan.cc/samba_linux_windows/ 主要有两步 ...