如何在 Mongodb 中添加/更新动态计数器?
这是我的 CSV 文件:
12;France;http://www.google.com
12;France;http://www.google.com
对于每一行,我用来填充 Mongo 的 $field[] 结构 对象如下所示:
array(18) {
["date_day"]=> int(12)
["url"]=> string(21) "http://www.google.com"
["country"]=> string(6) "France"
}
对于这两行中的每一行,我调用以下内容:
$result = $coll->update ( array ( 'ts_day' => $field['date_day'] ,'url'=>$field['url']),array('$addToSet' => array ( "countries" => array ( 'name' =>$field['country'] )) ),array ('upsert' => true ));
$result = $coll->update ( array ( 'ts_day' => $field['date_day'] ,'url' => $field['url'] , 'countries.name' => $field['country'] ),array ( '$inc' => array( 'countries.$.views'=> 1) ) ,array ( 'upsert' => true));
我不明白为什么我会得到一个额外的 { "name" : "France" } 对象 “国家”数组,没有“视图”计数器,尽管计数器 在country.france.views中适当增加(其值为2, 这是正确的):
{ "_id" : ObjectId("4eeb0e6cd86450af72f775be"), "url" : "http://www.google.com", "countries" : [ { "name" : "France", "views": 2 }, { "name" : "France" } ], "ts_day" : 12 }
对这个孤独的{“name”:“France”}有什么想法吗?蒙戈错误或 对我的误解?
谢谢 !
Here is my CSV file :
12;France;http://www.google.com
12;France;http://www.google.com
For each line, the $field[] structure I use to populate my Mongo
object looks like the following :
array(18) {
["date_day"]=> int(12)
["url"]=> string(21) "http://www.google.com"
["country"]=> string(6) "France"
}
For each of these two lines, I call the following :
$result = $coll->update ( array ( 'ts_day' => $field['date_day'] ,'url'=>$field['url']),array('$addToSet' => array ( "countries" => array ( 'name' =>$field['country'] )) ),array ('upsert' => true ));
$result = $coll->update ( array ( 'ts_day' => $field['date_day'] ,'url' => $field['url'] , 'countries.name' => $field['country'] ),array ( '$inc' => array( 'countries.$.views'=> 1) ) ,array ( 'upsert' => true));
I don't understand why I get an extra { "name" : "France" } object in
the "countries" array, with no "views" counter, although the counter
is properly incremented in countries.france.views (whose value is 2,
which is correct) :
{ "_id" : ObjectId("4eeb0e6cd86450af72f775be"), "url" : "http://www.google.com", "countries" : [ { "name" : "France", "views": 2 }, { "name" : "France" } ], "ts_day" : 12 }
Any idea for this lonely { "name" : "France" } ? Mongo bug or
misunderstanding of mine ?
Thank you !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来您似乎太沉迷于使用标准 mongoimport/export 工具来处理 CSV 文件了。
如果您查看源代码,您会发现这两个工具是相当简单的客户端应用程序,它们利用 MongoDB C++ 驱动程序。如果它们是用 Python 或 Ruby 编写的,则只需 5-10 行长。
为什么不简单地编写一个新脚本来读取 CSV 文件并按照您想要的方式插入文档呢?想做聚合?在客户端代码中执行此操作!想要完全控制架构吗?你已经准备好了!
事实上,这将是最好的前进方式——提供 mongoimport/export 是为了方便而不是全面。如果您的数据摄取过程需要在将大量文档写入数据库后对其进行大量更新,您甚至可能会开始看到压缩和性能方面的问题。
It sounds like you're getting too hung up on using the standard mongoimport/export tools to process your CSV files.
If you check out the source code, you'll notice that these two tools are rather simple client applications that utilize the MongoDB C++ driver. Were they written in Python or Ruby, they'd like only be 5-10 lines long.
Why don't you simply write a new script that reads in the CSV file and inserts the documents in exactly the way you'd like? Want to do aggregation? Do it in client code! Want total control over the schema? You're set!
In fact, this would be the best way forward -- mongoimport/export is provided for convenience not comprehensiveness. If your data ingestion process requires significantly updating a large number of documents once they've already been written to the database, you may even start to see issues with compaction and performance.
您需要使用 $inc 运算符。如果目标字段符合您指定的条件,这将增加目标字段。
http://www.mongodb.org/display/DOCS/Updating#Updating- %24inc
You need to use $inc operator. This will increment the target field, if it matches the criteria you specified.
http://www.mongodb.org/display/DOCS/Updating#Updating-%24inc
这可以解决问题:
$result = $coll->update ( array ( 'ts_year' => $field['date_year'] , 'ts_month' => $field['date_month'] , 'ts_day' => ; $field['date_day'] , 'asset' => $field['url'] ),
array ( '$inc' => array( "countries.".$field['country'].".views" => 1) ) ,array ( 'upsert' => true));
This does the trick :
$result = $coll->update ( array ( 'ts_year' => $field['date_year'] , 'ts_month' => $field['date_month'] , 'ts_day' => $field['date_day'] , 'asset' => $field['url'] ),
array ( '$inc' => array( "countries.".$field['country'].".views" => 1) ) ,array ( 'upsert' => true));