0

私のサンプルコード:

<?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が挿入されないようにするにはどうすればよいですか?ありがとう。

4

1 に答える 1

1

私がそれを正しく理解した場合、あなたの貼り付けられたコードは毎回このように実行されますか?
別のIPエントリを取得する際の問題は'$addToSet' => array('visitors' => array('ip' => $ip))'$addToSet' => array('visitors' => array('ip' => $ip))、配列にIPのみのフィールドが含まれていないため、別のIPエントリが挿入されることです(フィールドにはさらにpageview属性があります)。完全に一致する必要があります。
この問題のガイドラインがあるかどうかはわかりませんが、ドキュメントの構造として、次のようなものを使用する必要があると思います。

{_id:ObjectId(.....)、...、訪問者:{192.168.1.1:{pageview:1}}。したがって、この更新コマンドを(mongoshell構文で)実行するだけで、両方の更新をさらに1つに結合できます:):

db.c.update({"url":"/test.php","date":"today"},{$inc : {"192.168.1.1" : {pageview:1}, pageview: 1}},true)ドキュメントを更新します。とにかく、他の方法では機能しないため、これらのドットを他の文字に置き換える必要があります。

于 2012-06-15T06:51:51.990 に答える