猫鼬在特定记录中查找嵌套记录

Mongoose find nested records in specific record

本文关键字:记录 嵌套 查找      更新时间:2023-09-26

我把我的猫鼬模型/模式设置成这样:

var servers = mongoose.model('Servers', new mongoose.Schema({
    server_id : String,
    timestamps: []
}));

我保留服务器的记录,存储它们的服务器 ID 和一个包含 unix 时间戳的数组,该数组在它们收到请求时填充/更新。

我想查询时间戳数组,以查找两个时间戳之间的结果,针对特定server_id,例如,在伪代码中,我正在尝试做这样的事情;

'find servers.timestamps between timeFrom and timeTo where server_id = serverId'

一种方法是,如果您的MongoDB服务器3.2.X或更高,则使用$filter运算符。以下示例过滤timestamps数组,使其仅包含给定范围内的时间戳,即 timeFrom <= t <= timeTo

servers.aggregate([
    { 
        "$match": { 
            "server_id": serverId,
            "timestamps": {
                "$gte": timeFrom,
                "$lte": timeTo
            }
        } 
    },
    {
        "$project": {
            "server_id": 1,
            "timestamps": {
                "$filter": {
                    "input": "$timestamps",
                    "as": "t",
                    "cond": {
                        "$and": [
                            { "$gte": [ "$$t", timeFrom ]  },
                            { "$lte": [ "$$t", timeTo ]  }
                        ]                       
                    }
                }
            }
        }
    }
]).exec(function (err, result){
    console.log(result);
});

另一种方法(如果您的驱动程序不支持 MongoDB 3.2.X 或更高版本,即支持 >=2.6.X<=3.0.X (是使用 $map $setDiference 运算符的组合来投影一个过滤数组,您可以在其中过滤掉(使用 $setDiference (假值(从 $map 运算符派生(, 如以下示例所示:

servers.aggregate([
    { 
        "$match": { 
            "server_id": serverId,
            "timestamps": {
                "$gte": timeFrom,
                "$lte": timeTo
            }
        } 
    },
    {
        "$project": {
            "server_id": 1,
            "timestamps": {
                "$setDifference": [
                    {
                        "$map": {
                            "input": "$timestamps",
                            "as": "t",
                            "in": {
                                "$cond": [
                                    { 
                                        "$and": [
                                            { "$gte": [ "$$t", timeFrom ]  },
                                            { "$lte": [ "$$t", timeTo ]  }
                                        ]
                                    },
                                    "$$t",
                                    false
                                ]
                            }
                        }
                    },
                    [false]
                ]
            }
        }
    }
]).exec(function (err, result){
    console.log(result);
});