MongoDB统计文档(Document)的数组(Array)中的各个元素出现的次数
一,问题描述
【使用 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 组合多个条件查询($and、$in、$gte、$lte)
原文:http://www.cnblogs.com/hapjin/p/7944404.html
MongoDB统计文档(Document)的数组(Array)中的各个元素出现的次数的更多相关文章
- iOS 判断数组array中是否包含元素a,取出a在array中的下标+数组方法详解
目前找到来4个解决办法,第三个尤为简单方便 NSArray * arr = @["]; //是否包含 "]) { NSInteger index = [arr indexOfObj ...
- mongodb的基本操作与插入文档(document)
一.mongodb的基本操作: 1.查看mongodb当前所有的databases : show dbs 2.选择数据库(database) : use databaseName(该数据库不存在则会自 ...
- Mongodb嵌套文档的改动-利用数组改动器更新数据
初学mongodb的可能和我一样有个疑问.mongodb是文档型的,那么假设一个文档嵌套另外一个文档,假设对这个嵌套文档进行增删改查呢. 就像例如以下这样:.怎样对auther里面的name进行增删改 ...
- mongodb查询文档
说到查询,我们一般就想起了关系型数据库的查询了,比如:order by(排序).limit(分页).范围查询(大于某个值,小于某个值..,in查询,on查询,like查询等待很多),同样mongodb ...
- Javascript学习8 - 脚本化文档(Document对象)
原文:Javascript学习8 - 脚本化文档(Document对象) 每个Web浏览器窗口(或帧)显示一个HTML文档,表示这个窗口的Window对象有一个document属性,它引用了一个Doc ...
- MongoDB数据库文档操作
前面的话 本文将详细介绍MongoDB数据库关于文档的增删改查 数据类型 在介绍文档操作之前,首先要了解MongoDB的数据类型 MongoDB支持许多数据类型,包括 1.字符串 - 这是用于存储数据 ...
- MongoDB插入文档
db.collection.insertOne() 插入单个文档.db.collection.insertMany() 插入多个文档.db.collection.insert() 插入单/多个文档. ...
- PyRevit开发第一步:获取Revit文档Document
1.安装PythonShell插件 PythonShell 2018 插件下载 交流QQ群: 17075104 新建项目后,运行功能Python Shell, 在弹出的窗口中复制或输入以下引用代码模块 ...
- 【ElasticSearch】:索引Index、文档Document、字段Field
因为从ElasticSearch6.X开始,官方准备废弃Type了.对应数据库,对ElasticSearch的理解如下: ElasticSearch 索引Index 文档Document 字段Fiel ...
随机推荐
- shell中,2>&1详解
我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令.首先我们把这条命令大概分解下,首先就是一个nohup表示当前用户和系 ...
- SSH防暴力破解脚本
crontab -e 编辑添加一下内容 1 1 * * * sh /root/bin/Denyhosts.sh 脚本内容 #!/bin/bash #Denyhosts SHELL SCRIPT #20 ...
- 2019 校内赛 RPG的地牢猎手(bfs+优先队列)
Problem Description Luke最近沉迷一款RPG游戏,游戏中角色可以进入地牢关卡,只要顺利走出地牢就可以获得奖励.地牢表示为n行m列的块矩阵,其中每个块只可以是障碍块.入口.出口或数 ...
- 区块链使用Java,以太坊 Ethereum, web3j, Spring Boot
Blockchain is one of the buzzwords in IT world during some last months. This term is related to cryp ...
- 用foobar进行码率转换 适用与sacd-r转成低码率
之前下载了不少高清音频,有黑胶转录的也有母带文件.这些高清音频大都是24bit,采样率96khz或者88.2khz或者更高.而我想将部分精品专辑刻录成cd.首先我需要将这些文件转换为16bit,44. ...
- agc032
T1 题意:你要进行n次操作,第i次选择一个数k∈[1,i],并插入到当前序列的第k个位置.给定目标序列,输出操作序列.100,2s. 解:冷静分析一波,我们可以从后往前确定操作序列.这样每次确定一个 ...
- A1122. Hamiltonian Cycle
The "Hamilton cycle problem" is to find a simple cycle that contains every vertex in a gra ...
- A1003. Emergency
As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...
- 【BZOJ3289】Mato的文件管理 莫队+树状数组
题目大意:给定一个长度为 N 的序列,M 个询问,每次询问区间逆序对的个数. 题解:用树状数组加速答案转移. 代码如下 #include <bits/stdc++.h> #define f ...
- MD5加密解密类(asp.net)&使用MD5过时处理
加密类 #region ========加密======== /// <summary> /// 加密 /// </summary> /// <param name=&q ...