Javascript 使用Node.js的MongoDB聚合性能问题

Javascript 使用Node.js的MongoDB聚合性能问题,javascript,node.js,mongodb,performance,Javascript,Node.js,Mongodb,Performance,我对MongoDB聚合性能有一些疑问 我的数据库有43'000'000个文档,当我试图调用后端时,它从未响应(我确信问题来自数据库,因为文档集较小,一切正常) 我实际上使用的是Node.js,它是Mongoose模块 这是模型的一个示例 var PingSchema = new Schema({ provider: String, from_zone: String, to_zone: String, from_host: String, to_host:

我对MongoDB聚合性能有一些疑问

我的数据库有43'000'000个文档,当我试图调用后端时,它从未响应(我确信问题来自数据库,因为文档集较小,一切正常)

我实际上使用的是Node.js,它是Mongoose模块

这是模型的一个示例

var PingSchema = new Schema({
    provider: String,
    from_zone: String,
    to_zone: String,
    from_host: String,
    to_host: String,
    icmp_seq: Number,
    ttl: Number,
    time: Number,
    timestamp: { type : Date, default: Date.now }
}).plugin(mongoosePaginate);

const Ping = mongoose.model('Ping', PingSchema);
我正在使用Express创建一些路由,这是来自后端的两个主要查询的代码

router.route('/pings/query/avgOfEveryPingOfSelectedDate').get(async (req, res, next) => {
    var start, end, sameRegion;

    start = new Date(req.query.start + "T00:00:00-00:00");
    end = new Date(req.query.end + "T23:59:59-00:00");
    sameRegion = parseInt(req.query.sameRegion);

    Ping.aggregate()
    .project({sameRegion: {$cmp: ['$from_zone', '$to_zone']}, provider: "$provider", time: "$time", timestamp: "$timestamp"})
    .match({$and: [{sameRegion: sameRegion}, {timestamp: {$gte: start, $lte: end}}]})
    .group({_id : "$provider", avg: { $avg: "$time" }, count: { $sum: 1 }})
    .exec(function (err, resp) {
        if (err) {
            // TODO
            console.log(err);
        } else {
            res.json(resp);
        }
    })
});

router.route('/pings/query/avgOfEveryDayOfSelectedYear').get(async (req, res, next) => {
    var year, provider, sameRegion;

    year = parseInt(req.query.year);
    provider = req.query.provider;
    sameRegion = parseInt(req.query.sameRegion);

Ping.aggregate()
    .project({sameRegion: {$cmp: ['$from_zone', '$to_zone']}, provider: "$provider", time: "$time", timestamp: "$timestamp", "year": {"$year":"$timestamp"}, "dayOfYear": { "$dayOfYear": "$timestamp" }})
    .match({$and: [{sameRegion: sameRegion}, {year: year}, {provider: provider}]})
    .group({_id : {"provider": "$provider", "dayOfYear": "$dayOfYear"}, avg: { $avg: "$time" }, count: { $sum: 1 }})
    .sort({"_id": 1})
    .exec(function (err, resp) {
        if (err) {
            // TODO
            console.log(err);
        } else {
            res.json(resp);
        }
    })
});
第一个查询输入两个日期并返回此范围内所有ping的平均时间。第二个需要一年和一个选定的提供者(一个简单的字符串),并返回所有符合条件的ping的平均值

我在问我的代码是不是错了(或者它需要一些优化),或者我是否应该做一些缓存或并行化的事情(也许MongoDB有一些这方面的功能?)

提前谢谢大家

编辑1: 也许allowDiskOption或某些索引是有用的

编辑2: 我已经在提供者和时间戳上实现了allowDiskOption和一些索引,但是查询仍然很慢。 这里的问题是:在这个大数据集上,这些查询太慢了

// By day in month
db.pings.aggregate(
    [
        {$project: {month: {"$month":"$timestamp"}}},
        {$match: {$and: [{provider: "AWS"},{month:8}]}},
        {$group:{_id: {"$dayOfYear":"$timestamp"}, avg: {$avg:"$time"}}},
        {$sort:{_id:1}}
    ],
    {
        allowDiskUse: true
    }
)

// In two dates
db.pings.aggregate(
    [
        {$match:{timestamp:{$gte:ISODate("2018-08-10T00:00:00.0Z"), $lte:ISODate("2018-08-18T23:59:59.0Z")}}},
        {$group:{_id: "$provider", avg: {$avg:"$time"}}}
    ],
    {
        allowDiskUse: true
    }
)
我现在要问的是:如何优化这些查询?


再次感谢

您是否尝试过将查询直接输入mongo并查看它需要多长时间?@Skami是的,它们需要精确的时间,这不是中间件的问题。