Mongoose在特定记录中查找嵌套记录

时间:2016-05-18 12:16:15

标签: javascript node.js mongodb mongoose

我的mongoose模型/架构设置如下:

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

我保存服务器记录,存储服务器ID以及包含unix时间戳的数组,这些数据在收到请求时会被填充/更新。

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

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

1 个答案:

答案 0 :(得分:1)

如果您的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)将使用 {{的组合3}} $map 运算符投影过滤后的数组,您可以过滤掉(使用 $setDiference )错误值(派生来自 $setDiference 运算符),如下例所示:

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);
});