Mongodb聚合查询

女生的网名这么多〃 提交于 2020-02-13 03:48:43

这个aggregate在mongodb中算是一个非常重量级的工具了,而且pipeline的管道模型的理论就是后面操作的数据源来源于上一次操作的结果

数据库中Aggregation   操作:

eg.

db.getCollection('follow_schedule').aggregate( [

 

 { "$match" : { "attention_timestamp" : { "$gte" : 1517414400000 , "$lte" : 1519833599000}}} ,

   { "$match" : { "doctorid" : "dt221955" , "way" : "来院随访"}} ,

{ "$group" : { "_id" : "$attention_timedot" , "count" : { "$sum" : 1} } }

 

])

常用操作说明:

数据库操作

说明

Spring data

$match  

 

用于筛选数据,{}中可以放入多条条件,多个条件用” , ”隔开

Aggregation.match(New Criteria()),

$group

分组,语义同SQL中的“group by”;”_id”为分组字段,是必须的,”count” 为对每个组执行的表达式计算(count为自定义名字)。表达式计算如下。

Aggregation.group("attention_timedot").count().as("count")

$project

指定哪些字段将会包含在输出中。默认情况下“_id”字段一定被包含,除非显式指定“_id : 0”才能排除掉;“0”或者false表示“不包含”,“1”或者true表示包含

Aggregation.project("doctorid","attention_timedot","count")

$unwind

将指定的数组结构拆解成多条document,其中指定的Field必须是数组

Aggregation.unwind("数组列名"),

$limit $skip

$sort

同Query中的limit、skip、$sort限定符

Aggregation.sort(newSort(new Order(Direction.DESC, "count"))),

Aggregation.skip(0),

Aggregation.limit(10),

 

 

Aggregation.project("d").and("").previousOperation().and("").nested(Aggregation.bind("", ""));

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Group可进行的表达式计算

  $sum:对每个组指定字段值进行累加计算。忽略非数字的值。

  $avg: 对每个group进行“平均值”,忽略非数字的值。

  $first: 返回每个group的第一条数据,顺序有$sort决定,如果没有排序,默认为文档的自然存储顺序

  $last: 返回每个group的最后一条数据,顺序有$sort决定,如果没有排序,默认为文档的自然存储顺序

  $max、$min:获取每个group中最大、最小值

      

Spring data中:

   Aggregation agg = Aggregation.newAggregation(

                                   Aggregation.match(

                                                 New Criteria(TableFieldName.attention_timestamp)

.gte(attrmap.get(TableFieldName.start_time))

.lte(attrmap.get(TableFieldName.end_time))

                                                 ), // 条件

                                   Aggregation.group("attention_timedot").count().as("count")//分组字段

                                   Aggregation.project("doctorid","attention_timedot","count")//返回字段

Aggregation.sort(new Sort(new Order(Direction.DESC, "count"))), // 排序

                                     Aggregation.skip(0), // 过滤

                                     Aggregation.limit(10) ,// 页数

Aggregation.lookup("doctor","doctorid","userid","inventory_docs")//多表联合查询

                     );

 

AggregationResults<BasicDBObject> results = mongoTemplate.aggregate(agg, "follow_schedule",BasicDBObject.class);

List<BasicDBObject> cat1UpdateCountList = results.getMappedResults();

 

其中:mongoTemplate.aggregate(agg, "follow_schedule",BasicDBObject.class);

第一个参数为Aggregation 第二个参数为要查询的表名 第三个参数为返回的数据类型

 

 

$lookup做多表关联处理

db.getCollection('edhealth').aggregate(

  [

      {

        $lookup:

          {

           from: "edhealth_record", //要关联的表

            localField: "userid",//当前表需要关联的键

            foreignField: "elderId",//外键,关联表对应的键

            as: "inventory_docs"//对应的外键集合的数据

          }

     },

    

     { $project : { "userid":1,"waist":1,"bloodType":1,"height":1, "inventory_docs":1}}  //要显示的字段

   

    ]

)

数据库中去重操作:

eg.查询给dt439815打过电话的人

db.getCollection('vcall_record').distinct("called",{"caller":"dt439815"})

 

    第一个参数为目标去重字段,第二个参数为筛选条件,筛选条件写入{}中,多个用“,”隔开

 

Spring data

 

Query query = Query.query(Criteria.where("caller").is("dt439815"));

  mongoTemplate.getCollection("vcall_record").distinct("called", query.getQueryObject());

 

 

 

 

示例1:

db.getCollection('jg_geracomium').aggregate([{$match:{"_id":"gd02137175"}},

{$lookup:{from:"jg_room",localField:"_id",foreignField:"geracomiumId",as:"result"}},

{$project:{"_id":0,"result":1}},{$unwind:"$result"},

{$lookup:{from:"jg_resthomebed",localField:"result._id",foreignField:"roomId",as:"data"}},

{$unwind:"$data"},

{$group:{"_id":"$data.roomId","count":{$min:"$data.price"}}}

])

 

 

 

示例2:

db.getCollection('user').aggregate([{$lookup:

{from:"user_account",localField:"userId",foreignField:"userId",as:"data"}},{$project:{"userId":1,"nickname":1,"data.accountId":1,"data.accountType":1,"data.accountMoney":1}},{$unwind:"$data"},{$match:{"data.accountId":"ac123456"}}])

 

 

 

 

示例3:

db.getCollection('jg_childUser').aggregate([ {$match:{"telephone":"18667945326"}},

{$lookup:

    {from:"jg_orderInfo",localField:"telephone",foreignField:"userTelephone",as:"data"}},

    {$project:{"nickName":1,"telephone":1,"data.orderNum":1,"data.userTelephone":1}},

    {$unwind:"$data"},

    {$group:{"_id":"$telephone","count":{$sum:1}}}

])

 

示例4:

db.getCollection('jg_childUser').aggregate([

   {"$group":{"_id":"$telephone"}},

    { "$lookup" :

    { "from" : "jg_orderInfo" , "localField" : "_id" , "foreignField" : "userTelephone" , "as" : "data"}} ,

 

    {"$group":{"_id":"$_id","count":{"$sum":1}}},

    { "$lookup" :

    { "from" : "jg_childUser" , "localField" : "_id" , "foreignField" : "telephone" , "as" : "dd"}} ,

 

    {"$group":{"_id":{"telephone":"$_id","count":"$count"},"first":{"$first":"$dd"}}},

    {"$sort":{"first.createTimestamp":-1}},

    {"$limit":10},

    {"$skip":0}

])

 

 

对应spring-date

Aggregation newAggregation = Aggregation.newAggregation(Aggregation.group("telephone"),

                            Aggregation.lookup("jg_orderInfo", "_id", "userTelephone", "data"),

                            Aggregation.unwind("data"),

                            Aggregation.group("_id").count().as("count"),

                            Aggregation.lookup("jg_childUser", "_id", "telephone", "reslut"),

                            Aggregation.unwind("reslut"),

                            Aggregation.group("_id","count").first("reslut").as("first"),

                            Aggregation.sort(new Sort(new Order(Direction.DESC, "first.createTimestamp")))

                         );

示例5

db.getCollection('jg_childUser').aggregate([

{"$match":{"telephone":{$ne:null}}},

{"$group":{"_id":"$telephone"}},

{"$lookup":

    {"from" : "jg_orderInfo","localField":"_id","foreignField":"userTelephone","as":"data"}}, 

{"$unwind":"$data"},

{"$group":{"_id":"$_id","count":{"$sum":1}}},

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

{"$lookup":

    {"from":"jg_childUser","localField":"_id","foreignField":"telephone","as":"res"}},

{"$unwind":"$res"},

{"$group":{"_id":"$_id","total":{"$first":"$count"},"appName":{"$first":"$res.appName"},"province":{"$first":"$res.province"},

           "city":{"$first":"$res.city"},"name":{"$first":"$res.nickName"},"createtime":{"$first":"$res.createTimestamp"}}},

{"$sort":{"createtime":-1}}

 ])

 

对应spring-data

Aggregation newAggregation = Aggregation.newAggregation(

                            Aggregation.match(new Criteria("telephone").ne(null)),

                            Aggregation.group("telephone"),

                            Aggregation.lookup("jg_orderInfo", "_id", "userTelephone", "data"),

                            Aggregation.unwind("data"),

                            Aggregation.group("_id").count().as("count"),

                            Aggregation.lookup("jg_childUser", "_id", "telephone", "res"),

                            Aggregation.unwind("res"),

                     Aggregation.group("_id").first("count").as("total").first("res.appName").as("appName").first("res.province").as("province")

                     .first("res.city").as("city").first("res.nickName").as("nickName").first("res.createTimestamp").as("createtime"),

                            Aggregation.sort(new Sort(new Order(Direction.DESC, "createtime")))

                         );

 

模糊查询:

{"$match":{"name":{"$regex":"^.*李.*$","$options":"i"}}};

 

$regex操作符的使用

$regex操作符中的option选项可以改变正则匹配的默认行为,它包括i, m, x以及S四个选项,其含义如下

i 忽略大小写,{<field>{$regex/pattern/i}},设置i选项后,模式中的字母会进行大小写不敏感匹配。

m 多行匹配模式,{<field>{$regex/pattern/,$options:'m'},m选项会更改^和$元字符的默认行为,分别使用与行的开头和结尾匹配,而不是与输入字符串的开头和结尾匹配。

x 忽略非转义的空白字符,{<field>:{$regex:/pattern/,$options:'m'},设置x选项后,正则表达式中的非转义的空白字符将被忽略,同时井号(#)被解释为注释的开头注,只能显式位于option选项中。

s 单行匹配模式{<field>:{$regex:/pattern/,$options:'s'},设置s选项后,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符(\n),只能显式位于option选项中。

使用$regex操作符时,需要注意下面几个问题:

i,m,x,s可以组合使用,例如:{name:{$regex:/j*k/,$options:"si"}}

在设置索弓}的字段上进行正则匹配可以提高查询速度,而且当正则表达式使用的是前缀表达式时,查询速度会进一步提高,例如:{name:{$regex: /^joe/}

 

Spring-data 实现:

new Criteria(key1).regex(Pattern.compile("^.*" + attrmap.get(key) + ".*$", Pattern.CASE_INSENSITIVE))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!