zoukankan      html  css  js  c++  java
  • Mongodb聚合查询

    这个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选项后,会改变模式中的点号(.)元字符的默认行为,它会匹配所有字符,包括换行符( ),只能显式位于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))

  • 相关阅读:
    [matlab] 8.蚁群算法解决TSP问题
    [python] A*算法基于栅格地图的全局路径规划
    [python] RRT快速拓展随机树
    [matlab] 7.快速搜索随机树(RRT---Rapidly-exploring Random Trees) 路径规划
    [matlab] 6.粒子群优化算法
    [matlab] 5.字符运算与微积分
    [matlab] 4.M函数
    [matlab] 3.矩阵
    [python] 解决pip install download速度过慢问题 更换豆瓣源
    [matlab] 1.拟合
  • 原文地址:https://www.cnblogs.com/mlorct/p/9223199.html
Copyright © 2011-2022 走看看