Pul*_*wal 4 database mongodb node.js mongodb-query aggregation-framework
{
"_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")
}]
}
Run Code Online (Sandbox Code Playgroud)
我有一个包含数组的文档.我想从当前时间的最后2小时内选择所有那些没有response_log.created_at的文档,并且最后24个中的response_log.created_at计数小于3.
我无法弄清楚如何去做.请帮忙
您可以使用聚合框架来过滤文档.带有$match和$redact步骤的管道将进行过滤.
考虑运行以下聚合操作,其中$redact允许您$cond使用运算符处理逻辑条件,并使用系统变量$$KEEP"保留"逻辑条件为真的文档,或者$$PRUNE"删除"条件为false的文档.
此操作类似于具有$project选择集合中的字段的管道,并创建一个新字段,该字段保存逻辑条件查询的结果,然后是后续的$match,除了$redact使用更高效的单个管道阶段:
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;
});
Run Code Online (Sandbox Code Playgroud)
在上面的聚合操作中,如果执行第一个$match管道步骤
collection.aggregate([
{ '$match': { 'response_log.created_at': { '$gt': last2hours } } }
])
Run Code Online (Sandbox Code Playgroud)
返回的文档将是在"response_log.created_at"当前时间的最后2小时内没有的文件,其中使用API 使用momentjs库last2hours创建变量.subtract
然后,前面的管道$redact将使用$cond三元运算符进一步过滤上面的文档,该运算符计算$size用于获取计数的逻辑表达式,并$filter返回具有与其他逻辑条件匹配的元素的已过滤数组
{
'$lt': [
{
'$size': {
'$filter': {
'input': '$response_log',
'as': 'res',
'cond': { '$lt': ['$$res.created_at', last24hours] }
}
}
},
3
]
}
Run Code Online (Sandbox Code Playgroud)
到$$KEEP文档,如果这个条件为真或$$PRUNE为"删除",其中分析的状态是假文件.
我知道这可能不是您正在寻找的答案,但这可能不是 Mongo 的最佳用例。在关系数据库中很容易做到这一点,在支持 Map/Reduce 的数据库中也很容易做到这一点,但在 Mongo 中则不然。
如果您的数据看起来不同,并且您将每个日志条目保留为引用该对象(在本例中为 id 5852725660632d916c8b9a38)的单独文档,而不是成为该对象的一部分,那么您可以对具有该对象的最新日志条目进行简单查询ID。如果我打算使用 Mongo 来实现这一点(我不会),这就是我在你的情况下会做的事情。
您还可以做的是在 Mongo 中保留一个单独的集合,或者向此处的对象添加一个新属性,该属性将存储添加的活动的最新日期。然后就很容易搜索到你需要的东西了。
当您使用像 Mongo 这样的数据库时,您的数据的外观必须反映您需要用它做什么,就像在本例中一样。添加最后的营销活动日期并在添加的每个营销活动中更新它,可以让您轻松搜索所需的营销活动。
如果您希望能够进行任何搜索和聚合,那么使用关系数据库可能会更好。
| 归档时间: |
|
| 查看次数: |
2508 次 |
| 最近记录: |