{
    "_id" : ObjectId("5852725660632d916c8b9a38"),
    "response_log" : [
    {
        "campaignId" : "AA",
        "created_at" : ISODate("2016-12-20T11:53:55.727Z")
    },
    {
        "campaignId" : "AB",
        "created_at" : ISODate("2016-12-20T11:55:55.727Z")

    }]
}

我有一个包含数组的文档。我想选择所有从当前时间过去2小时内没有response_log.created_at的文档,并且过去24天的response_log.created_at计数少于3。

我不知道该怎么做。请帮忙

最佳答案

您可以使用聚合框架来过滤文档。具有 $match $redact 步骤的管道将进行过滤。

考虑运行以下聚合操作,其中 $redact 允许您使用 $cond 运算符处理逻辑条件,并使用系统变量 $$KEEP 来“保留”逻辑条件为true或 ojit_re条件为假的文件。

此操作类似于使用 $$PRUNE 管道,该管道选择集合中的字段,并创建一个新字段来保存逻辑条件查询的结果,然后再保存后续的 $project ,不同之处在于 $match 使用单个管道阶段效率更高:

var moment = require('moment'),
    last2hours = moment().subtract(2, 'hours').toDate(),
    last24hours = moment().subtract(24, 'hours').toDate();

MongoClient.connect(config.database)
    .then(function(db) {
        return db.collection('MyCollection')
    })
    .then(function (collection) {
        return collection.aggregate([
            { '$match': { 'response_log.created_at': { '$gt': last2hours } } },
            {
                '$redact': {
                    '$cond': [
                        {
                            '$lt': [
                                {
                                    '$size': {
                                        '$filter': {
                                            'input': '$response_log',
                                            'as': 'res',
                                            'cond': {
                                                '$lt': [
                                                    '$$res.created_at',
                                                    last24hours
                                                ]
                                            }
                                        }
                                    }
                                },
                                3
                            ]
                        },
                        '$$KEEP',
                        '$$PRUNE'
                    ]
                }
            }
        ]).toArray();
    })
    .then(function(docs) {
        console.log(docs)
    })
    .catch(function(err) {
        throw err;
    });

解释说明

在上面的聚合操作中,如果执行第一个 $redact 管道步骤
collection.aggregate([
    { '$match': { 'response_log.created_at': { '$gt': last2hours } } }
])

返回的文档将是从当前时间开始的最近2个小时内没有$match的文档,其中使用 "response_log.created_at" API通过momentjs库创建了last2hours变量。

然后,前面带有 subtract 的管道将通过使用 $redact 三元运算符对上面的文档进行进一步过滤,该三元运算符对该逻辑表达式进行求值,该逻辑表达式使用 $cond 来获取计数,并通过 ojit_r将带有已过滤数组的元素返回到ojit_r符合其他逻辑条件
{
    '$lt': [
        {
            '$size': {
                '$filter': {
                    'input': '$response_log',
                    'as': 'res',
                    'cond': { '$lt': ['$$res.created_at', last24hours] }
                }
            }
        },
        3
    ]
}

如果此条件为true,则将其转换为 $size ,或者将 $filter “删除”为评估条件为假的文档。

关于node.js - 在MongoDB中汇总后查找,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43605730/

10-09 14:52