查询类报表mongodb语句设计

来源:互联网 发布:网络棋牌源码 编辑:程序博客网 时间:2024/06/06 04:29

1. 需求分析

表单分A、B两张表单。Afield1、Bfield1为两张表的关联字段;Afield2、Bfield2为需要查询的字段。

两张表的数据都存储在test表中。

2. 测试数据

{  "_id" : ObjectId("59ddb60c008ad60934c5194d"),  "A-field1" : 1,  "A-field2" : 2,  "formid" : "A"}{  "_id" : ObjectId("59ddb658008ad60934c5194f"),  "B-field1" : 1,  "B-field2" : 2,  "formid" : "B"}{  "_id" : ObjectId("59ddb9da008ad60934c51952"),  "A-field1" : 2,  "A-field2" : 2,  "formid" : "A"}{  "_id" : ObjectId("59ddbcc1008ad60934c51955"),  "A-field1" : 1,  "A-field2" : 4,  "formid" : "A"}

3. 查询语句

使用聚合进行查询,第一版sql

db.test.aggregate([    {        // 我们指定查询我们需要的字段,即关联字段和查询的字段        // 我们要根据关联的字段为每条数据生成一个分组的key,我们就可以通过分组把数据关联起来,分组key的逻辑:如果A-field1字段存在,则key值为A-field1字段的值,B-field1字段存在,则key值为B-field1字段的值,因为两个字段分属不同的表单,所以不会同时存在一条数据上,所以需要用到ifNull来判断        "$project" :{            "Afield1": "$A-field1",            "Afield2": "$A-field2",            "Bfield1": "$B-field1",            "Bfield2": "$B-field2",            "formid" : 1,            "groupkey":{                  $ifNull: [ "$A-field1", {                      $ifNull: [ "$B-field1", null ]                  } ]              }        }     },{        // 我们根据分组字段,把能相互关联的字段进行分组查询, fieldA为A表的数据,fieldB为B表的数据        "$group" :{             _id : { "groupkey" : "$groupkey" },             "fieldA" : {$push:  { Afield2 :  "$Afield2" } },             "fieldB" : {$push:  { Bfield2 : "$Bfield2" } }        }    },    {         // 我们把数组为空的数据过滤掉        $project: {            _id : 1,             fieldA: {                $filter: {                   input: "$fieldA",                   as: "fieldA",                   cond: { $ne: [ "$$fieldA", {} ] }                }            },            fieldB: {                $filter: {                input: "$fieldB",                   as: "fieldB",                   cond: { $ne: [ "$$fieldB", {} ] }                }            }          }    },{        // 查询数据后我们要横向拆分数据,我们得计算出一组数据中会生成多少行数据,为什么要做这件事,因为... 不这么干没法做翻页        $project:{            _id : 1,            fieldA : 1,            fieldB : 1,            rowCount : { $cond: { if: { $gte: [ { $size: "$fieldA" }, { $size: "$fieldB" } ] }, then: { $size: "$fieldA" }, else: { $size: "$fieldB" } }}         }    },{        // 然后把行数拆分成索引        $project:{            _id : 1,            fieldA : 1,            fieldB : 1,            rowCount : { $range: [ 0, "$rowCount" ] }        }    },{        // 根据索引拼表格数据        $project : {            data : {                $map:                 {                   input: "$rowCount",                   as: "index",                   in: { A :{ $arrayElemAt: [ "$fieldA", "$$index" ] }, B: { $arrayElemAt: [ "$fieldB", "$$index" ] }}                 }            }        }    },    // 然后进行数组拆分,完成数据    { $unwind : "$data" }    // 最后进行分页即可]);

优化语句