mongodb聚合查询

MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。

$sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在结果文档中插入值到一个数组中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在结果文档中插入值到一个数组中,但不创建副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

这里我们介绍一下聚合框架中常用的几个操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。

补充:

在mongodb中提供了很多与更新操作有关的方法,我们也可以叫它更新操作符。这些操作符主要可以分为两类:字段和数组。

字段组的主要包括:$inc、$rename、$setOnInsert、$set、$unset。

数组组的主要包括:$addToSet、$pop、$pullAll、$pull、$pushAll、$push、$each、$slice、$sort。

$inc

  语法:db.collection.update({ field: value }, { $inc: { field1: amount } } );

  为一个字段添加加上一个值,这个方法只能对数字操作,也就是说只能给数字加上一个值,当然这个值可以是负数。

$set

  语法:db.collection.update({ field: value1 }, { $set: { field1: value2 } } );

  当文档中包含该字段的时候,更新该字段值为value2,如果该文档中没有该字段,则为本文档添加一个字段file1,并为其赋值给value2。

$unset

语法:db.collection.update({ field: value1 }, { $unset: { field1: <arg> } } );

参数arg可以使用true或者空字符串””,这样都会删除一个字段。

$rename

  语法:{$rename: { <old name1>: <newname1>, <old name2>: <new name2>, ... } }

  为文档中的一个或者多个字段改名。

$setOnInsert

  语法:db.collection.update(<query>, { $setOnInsert:{ <field1>: <value1>, ... } },{upsert: true })

  $setOnInsert只有在upsert设置为true,并且被更新的文档不存在此集合中,需要插入一个新的文档的时候才起作用。在插入的时候会为新插入的文档添加给定的字段。

$push

  语法:db.collection.update(<query>, { $push:{ <field>: <value> } })

  将一个数字存入一个数组,分为三种情况,如果该字段存在,则直接将数字存入数组.如果该字段不存在,创建字段并且将数字插入该数组.如果更新的字段不是数组,会报错的.

$pushAll

  语法:db.collection.update({ field: value }, { $pushAll: { field1: [ value1, value2, value3 ] } } );

  将多个数值一次存入数组.

$addToSet

  语法:db.collection.update( { field: value }, {$addToSet: { field: value1 } } );

  与$push功能相同讲一个数字存入数组,不同的是如果数组中有这个数字,将不会插入,只会插入新的数据,同样也会有三种情况,与$push相同.

$pop

  语法:db.collection.update( {field: value }, { $pop:{ field:,<arg> } } )

  删除数组最后一个或者第一个元素。如果参数arg设置为1,删除最后一个元素,如果设置为-1,则删除第一个元素。

$pull

  语法:db.collection.update( { field: <query> },{ $pull: { field: <query> } } );

  删除数组中的一个元素,如果删除的字段不是数组,会报错。

$pullAll

  语法:db.collection.update( { field: value }, {$pushAll: { field1: [ value1, value2, value3 ] } } );

  删除数组中的多个值,跟pushAll与push的关系类似.

$each

         $each只能和$addToSet或者$push结合使用,将多个值一次存入数组。

$slice

  $slice需要和$push结合使用,截取一定长度的数组。参数num是小于或者等于0的数。如果num等于0表示的是返回的是一个空数组,如果是负数表示从后向前截取负数绝对值长度的数组。

$sort

  $sort将数组中的元素按照一定的规则进行排序,同样1表示正序,-1表示倒序。

  $sort必须与$push、$each结合使用,并且$each值的数组中的元素都必须为对象。

注: 详解   http://blog.csdn.net/mengxiangyue/article/details/18560357

在java中通过BasicDBObject使用:

BasicDBObject limit = new BasicDBObject();-------------字段名-------------BasicDBObject("聚合表达式","条件")limit.append("items", new BasicDBObject().append("$slice", new int[]{0, 15}));
  1 private static void mongodbOperating(){
  2         try {
  3             //有多种构造方法,选择一种(IP、port)
  4             Mongo m = new Mongo( "192.168.21.111" , 27017 );
  5             //选择数据库,如果没有这个数据库的话,会自动建立
  6             DB  db = m.getDB( "mydb" );
  7
  8             //建立一个集合,和数据库一样,如果没有,会自动建立
  9             DBCollection collection = db.getCollection("myCollectionTest");
 10
 11             BasicDBObject doc = new BasicDBObject();
 12             doc.put("name", "MongoDB");
 13             doc.put("type", "database");
 14             doc.put("count", 1);
 15
 16             BasicDBObject info = new BasicDBObject();
 17             info.put("x", 203);
 18             info.put("y", 102);
 19             doc.put("info", info);
 20
 21             //插入一条数据,数据如下
 22             // {
 23             //     "name" : "MongoDB",
 24             //     "type" : "database",
 25             //     "count" : 1,
 26             //     "info" : {
 27             //                 x : 203,
 28             //                 y : 102
 29             //               }
 30             //  }
 31             // 可以循环插入多条数据
 32             collection.insert(doc);
 33             //查找第一条数据,显示如下,_id是系统自动帮加上的,全局唯一
 34             //{ "_id" : "49902cde5162504500b45c2c" , "name" : "MongoDB" , "type" : "database" , "count" : 1 , "info" : { "x" : 203 , "y" : 102}}
 35             DBObject myDoc = collection.findOne();
 36             System.out.println(myDoc);
 37
 38             //插入多条数据
 39             for (int i=0; i < 100; i++) {
 40                 collection.insert(new BasicDBObject().append("i", i));
 41             }
 42
 43
 44             //获取文档条数
 45             System.out.println(collection.getCount());
 46
 47             //使用Cursor 获取所有文档
 48             DBCursor cursor = collection.find();
 49             try {
 50                 while(cursor.hasNext()) {
 51                     System.out.println(cursor.next());
 52                 }
 53             } finally {
 54                 cursor.close();
 55             }
 56
 57             //查找操作,获取单条记录
 58             //{ "_id" : "49903677516250c1008d624e" , "i" : 71 }
 59             BasicDBObject query = new BasicDBObject();
 60             query.put("i", 71);
 61             cursor = collection.find(query);
 62             try {
 63                 while(cursor.hasNext()) {
 64                     System.out.println(cursor.next());
 65                 }
 66             } finally {
 67                 cursor.close();
 68             }
 69
 70             //查找 i>50的项
 71             query = new BasicDBObject();
 72             query.put("i", new BasicDBObject("$gt", 50));  // e.g. find all where i > 50
 73             cursor = collection.find(query);
 74             try {
 75                 while(cursor.hasNext()) {
 76                     System.out.println(cursor.next());
 77                 }
 78             } finally {
 79                 cursor.close();
 80             }
 81
 82
 83             //查找 20<i<=30
 84             query = new BasicDBObject();
 85             query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30));  // i.e.   20 < i <= 30
 86             cursor = collection.find(query);
 87             try {
 88                 while(cursor.hasNext()) {
 89                     System.out.println(cursor.next());
 90                 }
 91             } finally {
 92                 cursor.close();
 93             }
 94
 95             //修改 i=71的一项
 96             query = new BasicDBObject();
 97             query.put("i", 71);
 98             BasicDBObject update = new BasicDBObject();
 99             update.put("i", 710);
100             DBObject dbobj = collection.findAndModify(query, update);
101             System.out.println(dbobj);
102
103             //修改 i=72的一项
104             query = new BasicDBObject();
105             query.put("i", 72);
106             update = new BasicDBObject();
107             update.put("i", 720);
108             WriteResult result = collection.update(query, update);
109             System.out.println(result);
110
111             //删除i=61的项
112             query = new BasicDBObject();
113             query.put("i", 61);
114             collection.findAndRemove(query);
115             //删除i=62的项
116             BasicDBObject remove = new BasicDBObject();
117             remove.put("i", 62);
118             collection.remove(remove);
119
120             //创建索引 1为升序、-1为降序
121             collection.createIndex(new BasicDBObject("i", 1));  // create index on "i", ascending
122
123             //获取索引列表
124             List<DBObject> list = collection.getIndexInfo();
125             for (DBObject o : list) {
126                 System.out.println(o);
127             }
128
129             //获取数据库列表
130             for (String s : m.getDatabaseNames()) {
131                 System.out.println(s);
132             }
133             //获取集合列表
134             Set<String> colls = db.getCollectionNames();
135             for (String s : colls) {
136                 System.out.println(s);
137             }
138
139             //删除数据库
140             //m.dropDatabase("my_new_db");
141
142
143         } catch (UnknownHostException e) {
144             // TODO Auto-generated catch block
145             e.printStackTrace();
146         }
147     }  
				
时间: 2024-10-05 04:48:46

mongodb聚合查询的相关文章

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({"te

记一次mongodb聚合查询

先说一下场景,产品中用到了简单的表单构造器,开始提供了一系列的控件,例如单行文本框.多行文本框.单选.复选.时间等,之后你可以拖拽控件自己组装你想要的表单……网上有很多的表单构造器,这里就不细说了,可能功能有多有少,但是原理类似.因为这种表单的这种实现方式,我们不单单要存储表单的真实数据,还要存储对应表单的配置数据来渲染表单的样子.这里不细说配置相关的事情,细说一下表单数据的存储和查询. 对于一条记录有很多共有属性:主键ID.创建用户ID.创建时间.表单ID(用于读取表单配置)等一些业务数据,这

python操作mongodb之二聚合查询

#聚合查询 from pymongo import MongoClient db = MongoClient('mongodb://10.0.0.9:27017/').aggregation_example #准备数据 result = db.things.insert_many([{"x": 1, "tags": ["dog", "cat"]}, {"x": 2, "tags": [&

MongoDB的使用学习之(七)MongoDB的聚合查询(两种方式)附项目源码

先来张在路上-- 此项目是用Maven创建的,没有使用Maven的,自己百度.谷歌去:直接用Junit测试就行,先执行里面的save方法,添加10000条测试数据提供各种聚合查询等. 废话不多说,上干货-- 一.MongoDB数据库的配置(mongodb.xml) 以下是我自己的配置,红色字体请改为自己本机的东东,你说不懂设置端口,不会创建数据库名称,不会配置用户名密码,那有请查阅本系列的第4节(MongoDB的使用学习之(四)权限设置--用户名.密码.端口==),你说懒得设置,那就@#¥%--

mongodb高级聚合查询

在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mongodb v3.6 目录 mongo与mysql聚合类比 aggregate简介 aggregate语法 aggregate常用pipeline stage介绍(本文核心) mongo与mysql聚合类比 为了便于理解,先将常见的mongo的聚合操作和mysql的查询做下类比: SQL 操作/函数

Mongodb聚合操作之读书笔记

Mongodb聚合操作 读书笔记 mongodb,两种计算聚合pipeline和mapreduce pipeline查询速度快于mapreduce,但MapReduce能够在多台Server上并行执行复杂的聚合逻辑. mongodb不允许Pipeline的单个聚合操作占用过多的系统内存,如果一个聚合操作消耗20%以上的内存,那么mongodb直接停止操作,并向客户端输出错误消息. Pipeline方式使用db.collection.aggregate()函数进行聚合运算,运算速度较快,操作简单.

【Mongodb教程 第十一课 】MongoDB 聚合

聚合操作过程中的数据记录和计算结果返回.聚合操作分组值从多个文档,并可以执行各种操作,分组数据返回单个结果.在SQL COUNT(*)和group by 相当于MongoDB的聚集. aggregate() 方法 对于在MongoDB中聚集,应该使用aggregate()方法. 语法: aggregate() 方法的基本语法如下 >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) 例子: 在集合中,有以下的数据: { _id: ObjectId(

MongoDB 聚合管道(Aggregation Pipeline)

MongoDB 聚合管道(Aggregation Pipeline) - 张善友 时间 2013-12-27 22:40:00            博客园_张善友相似文章 (0)原文                  http://www.cnblogs.com/shanyou/p/3494854.html添加到推刊 收藏到推刊创建推刊 收 藏  取消 已收藏到推刊! 创建推刊 × Modal header --> 请填写推刊名 描述不能大于100个字符! 权限设置: 公开    仅自己可见

mongodb聚合(转)

聚合 是泛指各种可以处理批量记录并返回计算结果的操作.MongoDB提供了丰富的聚合操作,用于对数据集执行计算操作.在 mongod 实例上执行聚合操作可以大大简化应用的代码,并降低对资源的消耗. 聚合有比较简单的 count 计算总数:distinct去重:group by 分组.也有比较复杂的管道聚合.下面将分别讲述. appuser 集合 具有如下文档 {name:"人间四月",age:20,"locate":" 北京"} {name:&q