如何使用猫鼬在每个时间段每个对象密钥正确过滤1个文档

时间:2019-05-20 15:18:10

标签: node.js mongodb aggregate

我正在用mongoose在nodejs中构建一个Web api。 我正在开发的功能的严格目标是检索数据以绘制有关它们的图表。 it应用程序本身从本地打印机收集数据,并将数据发送到API(每10分钟一次)。 每次扫描都会生成一个mongo文档,其中包含有关打印机的所有必需信息,当然还有一个名为created的字段,它是一个isodate字段,代表文档的创建日期和时间。

我需要构建一个查询,该查询给出了打印机标识符,并且每个时间段每天需要为每个打印机标识符检索1次扫描(以下情况,因为这是每月变化)。第一个或最后一个是相同的。这是我的错误示​​例,因为我不确定如何进行此操作。

var codeList = [ webAppId1, webAppId2, webAppId3 ]; 
Printer.aggregate(
            [{
                    $match: {
                        codiceSim: {
                            $in: codeList
                        },
                        Created: {
                            $gte: new Date(new Date().setDate(new Date().getDate() - 30))
                        }
                    }
                }, {
                    $sort: {
                        Created: -1
                    }
                }, {
                    $project: {


                        year: {
                            $year: "$Created"
                        },
                        month: {
                            $month: "$Created"
                        },
                        day: {
                            $dayOfMonth: "$Created"
                        },
                        $original_doc: "$$ROOT"

                    }
                },
                {
                    $group: {

                        _id: {
                            codiceSim: "$codiceSim",
                            year: "$year",
                            month: "$month",
                            day: "$day"
                        }

                    }
                }
            ],
            function (err, printers) {
                if (err) res.send(err);
                res.json(printers);

            }).exec(function (printers) {

        });

我希望得到的结果与此类似(为清楚起见,以下应该是一周数据的结果,每天3台打印机每天1 doc)

[
 [{docScan1},{docScan2},{docScan3},{docScan4},{docScan5},{docScan6},{docScan7}],  <= printer1
 [{docScan1},{docScan2},{docScan3},{docScan4},{docScan5},{docScan6},{docScan7}],  <= printer2
 [{docScan1},{docScan2},{docScan3},{docScan4},{docScan5},{docScan6},{docScan7}]   <= printer3
]

我已经有一个查询来一次收集希望为一台打印机收集的相同数据,这是我的处理方法:

 Printer.aggregate(
 [{
    $match: {
      codiceSim: req.params.printerId,
      Created: {
        $gte: new Date(new Date().setDate(new Date().getDate() - 30))
      }
    }
  },

  {
    $project: {
      year: {
        $year: "$Created"
      },
      month: {
        $month: "$Created"
      },
      day: {
        $dayOfMonth: "$Created"
      },
      original_doc: "$$ROOT"
    }
  },
  {
    $group: {
      _id: {
        year: "$year",
        month: "$month",
        day: "$day"
      },
      docs: {
        $push: "$original_doc"
      }
    }

  },
  {
    $replaceRoot: {
      newRoot: {
        $arrayElemAt: ["$docs", 0]
      }
    }
  },
  {
    $sort: {
      Created: -1
    }
  }
],
function(err, printers) {
  if (err)
    res.send(err);
  res.json(printers);
});

需要在单个jquery异步调用中将来自不同打印机的一些数据注入同一图表中,以尝试找到解决方案,但我陷入了困境。谢谢

1 个答案:

答案 0 :(得分:0)

到目前为止,我选择完全绕过完善我的猫鼬aggr查询的解决方案,但我真的很期待在这方面的帮助。

这就是我的方法:

Printer.find({
            codiceSim: {
                $in: codeList
            },
            Created: {
                $gte: new Date(new Date().setDate(new Date().getDate() - 30))
            }
        }).lean().exec(function (err, printers) {
            if (err) res.send(err);
            var partial = new Array(codeList.length);
            var final = new Array(codeList.length);
            var times = [];
            for (var i = 0; i < 30; i++) {
                times.push(new Date(new Date().setDate(new Date().getDate() - (30 - i))));
            }
            codeList.forEach(function (item, index, arr) {
                partial[index] = printers.filter(printer => printer["codiceSim"] === item);
                if (partial[index] != undefined) {
                    times.forEach(function (cDate) {
                        var tmp = partial[index].filter(function (item) {
                            if (cDate.getFullYear() === item["Created"].getFullYear() &&
                                cDate.getMonth() === item["Created"].getMonth() &&
                                cDate.getDate() === item["Created"].getDate()) {
                                return item;
                            }
                        });
                        if (tmp != undefined && tmp.length > 0) {
                            if (final[index] === undefined) {
                                final[index] = new Array();
                            }
                            final[index].push(tmp[0]);
                        }

                    });
                }
            });
            res.json(final);
        });