提问者:小点点

如何从mongoDB查询中获取表结果


我正在尝试将mongo数据库中的一些结果映射到表中以生成Excel报告。我的Java代码从列表生成报告

在Mongo上,我能够使用以下命令获得所需的结果:

db.collection.find(query,projection).map(function).flat();

但是当我试图在Java上复制这个命令时,我发现val命令已被弃用,无法从Java驱动程序执行javascript。我想在数据库上执行映射,而不是在我的JAVA类中执行映射。如果需要,我想执行一个“本地查询”,而不是使用Spring数据来更好地操作我的报告查询。

我是mongo新手,在寻找解决方案时,我找到了聚合管道,但我不确定这是否能帮助我。

是否可以使用聚合管道或其他可以使用JAVA驱动程序执行的逗号获得相同的结果?

这是我的疑问

db.data_export.find({
$and: [
  { "data": {$exists: true}},
  {$or: [
    {"data.code1": {$exists: true}},
    {"data.code2": {$exists: true}},
    {"data.code3": {$exists: true}}
    ]
}, {
    companyId: 1,
    companyName: 1,
    "data.code1.iterations": 1,
    "data.code2.iterations":1,
    "data.code3.iterations":1
}).map(function(v) {
    let maxSize = 0;
    let codes = ['code1',
        'code2',
        'code3'];
    let codeFounded = [];
    for(const [key, value] of Object.entries(v.data)) {
        if(value && value.iterations){
            maxSize = Math.max(value.iterations.length, maxSize);
            codeFounded.push(key);
        }
    }
    let res = []
    for(let i=0; i<maxSize;i++){
        let o = {
            companyId: v.companyId,
            companyName: v.companyName
        }
        for(let s=0; s< codes.length; s++){
            const code = codes[s];
            let val = null;
            if(codeFounded.includes(code)){
                val = v.data[code].iterations[i];
            }
            o[code] = val;
        }
        res.push(o);
    }
    return res;
}).flat();

这是我的模型

{
    "companyId": 1,
    "companyName": "Company Name 1",
    "data": {
        "code1": {
            "iterations": [
                {
                    "procedure": "Functions"
                },
                {
                    "procedure": "Planning"
                },
                {
                    "procedure": "Monitoring"
                }
            ]
        },
    "code2": {
        "iterations": [
                {
                    "digitization": true
                }
            ]
        },
    "code3": {
        "iterations": [
                {
                    "meeting_freq": "Every month"                       
                }
            ]
        }
    }
}

这是我获得的结果,如下表所示:


共1个答案

匿名用户

这肯定有点棘手,但你是对的,它可以在单个本机查询中实现,以下是如何做到这一点:

db.collection.aggregate([
  {
    $match: {
      $or: [
        {
          "data.code1": {
            $exists: true
          }
        },
        {
          "data.code2": {
            $exists: true
          }
        },
        {
          "data.code3": {
            $exists: true
          }
        }
      ]
    }
  },
  {
    $addFields: {
      maxSize: {
        $reduce: {
          input: {
            "$objectToArray": "$data"
          },
          initialValue: 0,
          in: {
            $max: [
              "$$value",
              {
                $size: "$$this.v.iterations"
              }
            ]
          }
        }
      }
    }
  },
  {
    $addFields: {
      values: {
        $map: {
          input: {
            $range: [
              0,
              "$maxSize"
            ]
          },
          as: "iter",
          in: {
            $arrayToObject: {
              $map: {
                input: {
                  "$objectToArray": "$data"
                },
                as: "datum",
                in: {
                  k: "$$datum.k",
                  v: {
                    $ifNull: [
                      {
                        $arrayElemAt: [
                          "$$datum.v.iterations",
                          "$$iter"
                        ]
                      },
                      null
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $unwind: "$values"
  },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          {
            companyId: "$companyId",
            companyName: "$companyName",
            
          },
          "$values"
        ]
      }
    }
  }
])

蒙戈游乐场