2014-12-19 62 views
1

我想保持可疑流量的集合,它类似于下面的模式:MongoDB的日志记录可疑流量

"_id": ObjectId(###), 
"count": NumberInt(6), 
"ip": NumberInt(2147483647), 
"requests": { 
[ "uri": "/path/to/something/", 
    "last": NumberInt(1419023477) 
    "count": NumberInt(2) ], 
[ "uri": "/path/to/something/else/", 
    "last": NumberInt(1419023478) 
    "count": NumberInt(4) ] 
} 

有人可以帮我一个UPSERT会:

  • 添加请求URI到嵌入文档数组
  • 递增该URI的请求数
  • 设置该URI的最后一个请求日期
  • 最后增加总体要求数为IP

有人问我后我已经这么远:

$db->coll->update(array('ip' => $ip), 
       array('$addToSet' => array('req' => array('$set' => array('last' => $timestamp), 
                  '$inc' => array('count' => 1)))), 
       array('upsert' => true) 
       ); 

正如你所看到的,它没有搜索嵌入文档与相应的uri($ uri)

+2

您编写的代码,我们帮助解决它。而不是相反。 –

+0

请编辑该问题以添加您尝试过的实现。 – BatScream

+0

您的文档结构无效。请求是否意味着是一组对象? – wdberkeley

回答

0

我会改变你的文档结构。天真地,一个IP会向不断增长的URI集合提出请求。在没有绑定的情况下增长数组在MongoDB中并不是一个好主意,你会发现它处理它们很慢并且很麻烦。我建议的请求基础的每个文档,而不是在一个IP,所以这些文件看起来像:

{ 
    "ip" : "192.168.1.1", 
    "uri" : "/food/cookies/chocolatechip", 
    "timestamp" : ISODate("2014-12-22T18:44:26.860Z") 
} 

我把last在为datetime,这几乎总是你应该更喜欢在日期时间MongoDB的。我将它重命名为时间戳,因为它不再有意义称为last。另外,为什么你将ip作为一个数字来存储?我不是IP地址规则方面的专家,但我认为这很危险,因为192.168.1.1与19.216.81.1不是相同的IP地址,但是当您放弃。时,它们都会给出相同的数字。

现在,您可以用一个新文档的插入完成单个upsert的所有目标。您可以使用.count()查找计数并使用.sort()查找最近的请求,并可以对必要的查询进行索引,以便这些操作很快。