我有2个日期字段:date_start和date_end
$criteria = [
'_id'=>$data->thread,
'download_id'=>$data->id,
'ip'=>new MongoInt32(Helper::aton($data->remote_addr)),
];
$status = $nodeThreadsCollection->update($criteria,
[
'$set'=>[
'disconnected'=>(bool)$data->disconnected,
'date_end'=>new MongoDate(),
],
'$inc'=>[
'bytes_send'=>new MongoInt64($data->bytes_send),
]
],[
'upsert'=>true,
'w'=>1,
]
);
if(isset($status['updatedExisting']) && !$status['updatedExisting']) {
$nodeThreadsCollection->update($criteria,
[
'$set'=>[
'date_start'=>new MongoDate(),
],
],[
'w'=>0,
]
);
}
但它需要writeConcern = 1来获取插入状态并进行二次查询。 如何在一个查询中创建它?
答案 0 :(得分:5)
为了一次性完成这项工作,您可以:
<?php
/* Just random test setup */
$m = new MongoClient;
$nodeThreadsCollection = $m->test->test;
$data = new StdClass;
$data->thread = 5;
$data->id = 88;
$data->remote_addr = 76123123;
$data->disconnected = true;
$data->bytes_send = 7234;
*/
$criteria = [
'_id'=>$data->thread,
'download_id'=>$data->id,
'ip'=>new MongoInt32($data->remote_addr),
];
$status = $nodeThreadsCollection->update($criteria,
[
'$set'=>[
'disconnected'=>(bool)$data->disconnected,
'date_end'=>new MongoDate(),
],
'$setOnInsert'=>[
'date_start'=>new MongoDate(),
],
'$inc'=>[
'bytes_send'=>new MongoInt64($data->bytes_send),
]
],[
'upsert'=>true,
'w'=>1,
]
);
如果“upsert”仍然只是“插入”,$setOnInsert
运算符将只设置值。第一次(在新的集合上)运行此脚本显示:
{
"_id" : NumberLong(5),
"bytes_send" : NumberLong(7234),
"date_end" : ISODate("2014-01-10T10:11:16.507Z"),
"date_start" : ISODate("2014-01-10T10:11:16.507Z"),
"disconnected" : true,
"download_id" : NumberLong(88),
"ip" : 76123123
}
第二次运行它:
{
"_id" : NumberLong(5),
"bytes_send" : NumberLong(14468),
"date_end" : ISODate("2014-01-10T10:11:31.184Z"),
"date_start" : ISODate("2014-01-10T10:11:16.507Z"),
"disconnected" : true,
"download_id" : NumberLong(88),
"ip" : 76123123
}
另请参阅:http://docs.mongodb.org/manual/reference/operator/update/setOnInsert/