MongoDB更新插入与$inc和$addToSet


MongoDB upsert with $inc and $addToSet

我的示例代码:

<?php
$m = new Mongo();
$db = $m->selectDB('metrics');
$collection = new MongoCollection($db, 'counter');
$url = $_SERVER['REQUEST_URI'];
$ip = '192.168.1.1';
$user = 'testuser';
$today = date('Y-m-d');
//upsert 1st
$filter = array('url' => $url, 'date' => $today);
$data2 = array(
                '$inc' => array("pageview" => 1),
                '$addToSet' => array('visitors' => array('ip' => $ip))
);
$options = array("upsert" => true);
$collection->update( $filter, $data2, $options );

//update the pageview for unique ip after that
$filter1 = array( 'url' => $url, 'date' => $today, 'visitors' => array( '$elemMatch' => array( 'ip' => $ip ) ) );
$update1 = array( '$inc' => array( 'visitors.$.pageview' => 1 ) );
$collection->update( $filter1, $update1 );
?>

mongodb 中的数据:

这是第一次查看页面时正确的。

> db.counter.find();
{ "_id" : ObjectId("4fdaaf1176c5c9fca444ffd3"), "date" : "2012-06-14", "pageview" : 1, "url" : "/mongo/test.php", "visitors" : [ { "ip" : "192.168.1.1", "pageview" : 1 } ] }

刷新页面后,添加奇怪的数据:

> db.counter.find();
{ "_id" : ObjectId("4fdaaf1176c5c9fca444ffd3"), "date" : "2012-06-14", "pageview" : 2, "url" : "/mongo/test.php", "visitors" : [ { "ip" : "192.168.1.1", "pageview" : 2 }, { "ip" : "192.168.1.1" } ] }

如何更正查询并防止插入额外的 IP?谢谢。

如果我

做对了,您粘贴的代码每次都以这种方式执行?
您获得另一个 ip 条目的问题'$addToSet' => array('visitors' => array('ip' => $ip))'$addToSet' => array('visitors' => array('ip' => $ip))因为您的数组不包含只有一个 ip 的字段,它将插入另一个字段(您的字段还有一个网页浏览属性)。您需要有一个完全匹配。
不确定这个问题是否有一些指导方针,但我认为你应该使用这样的东西,作为文档结构:

{_id:ObjectId(.....),..., 访问者: { 192.168.1.1: {pageview:1}}.因此,您可以简单地运行此更新命令(使用mongoshell语法),该命令将两个更新进一步合并为一个:):

db.c.update({"url":"/test.php","date":"today"},{$inc : {"192.168.1.1" : {pageview:1}, pageview: 1}},true)更新您的文档。无论如何,您需要用其他字符替换这些点,否则它不起作用。