问题描述
我有一个MongoDB数据库,人们可以在其中输入相对任意的搜索条件(在这种情况下,他们经过了审查,但在概念上没有限制)。用户可以指定的条件示例如下:
{"$and": [
{"details.vulns": "cve-2019-19781"},]}
这对于搜索非常有效,但是,我希望也能够基于较旧的数据生成统计信息,为此,我使用了类似如下的汇总:
db.hosts.aggregate([
{"$sort": {"timestamp": 1}},{"$addFields": {
"condition": {$cond: [
{"$and": [
{"details.vulns": "cve-2019-19781"},]},1,]}
}},{"$project": {
"ip": "$ip","timestamp": "$timestamp","condition": "$condition",}},]);
这种查询的问题是MongoDB似乎不允许将$ cond与类似$details.vulns
的东西一起使用。我知道一种标准方法是解散,但是由于在执行代码之前尚不了解条件,因此除非我在自己的代码中重新实现MongoDB解析引擎,否则我无法知道要解散哪些字段。>
为更清楚地说明问题,这里有一些示例数据。请记住,这是简化的操作-实际数据包含许多不同的字段,我可能希望查询这些字段,因此上述有关展开的陈述并不是令人满意的解决方案:
// Objects
{ "_id" : ObjectId("5cfc73657e2438b115888d1b"),"ip" : NumberLong("12345"),"timestamp" : ISODate("2019-06-09T02:45:45Z"),"vulns" : [ "cve-2019-19781" ] },{ "_id" : ObjectId("5d04c5497e2438b115b06659"),"timestamp" : ISODate("2019-06-15T10:13:33Z"),"vulns" : [ "" ] },{ "_id" : ObjectId("5d108c52211d917c6ff48bfd"),"timestamp" : ISODate("2019-06-24T08:37:31Z"),"vulns" : [ "cve-2019-19781","other-vuln" ] },// Desired output from aggregate
{"ip" : NumberLong("12345"),"condition": 1 },{"ip" : NumberLong("12345"),"condition": 0 },
这里是否缺少替代方法,还是MongoDB只是缺乏在聚合过程中应用搜索子句的能力? 如果这样做的速度很慢,那我会很好的。
解决方法
不清楚您要寻找什么。你是这个意思吗?
nullptr
还是简单的$match?
您可以运行
{"$addFields": {
"condition": {$cond: [
{$eq: ["$details.vulns": "cve-2019-19781"]},1,]}
}},
或
var field = "ip";
db.hosts.aggregate([
{$unwind: field }
])
顺便说一句,您可以简单地写:
var condObj = JSON.parse('{"$and": [{"details.vulns": "cve-2019-19781"}]}');
db.hosts.aggregate([
{"$addFields": {
"condition": {$cond: [
condObj,]}
}}
]);