【问题标题】:Removing duplicate keys after $unwind in MongoDB aggregation在 MongoDB 聚合中删除 $unwind 后的重复键
【发布时间】:2016-05-27 03:53:08
【问题描述】:

使用 MongoDB,我正在对包含名为 tests 的数组的文档进行聚合管道,并使用 $unwind 操作将该数组展开为多个文档:

原始文件:

{"_id"=>"1867930", "tests"=> [
    {"status"=>"passed", "elapsed_time"=>26, "worker"=>11},
    {"status"=>"passed", "elapsed_time"=>34, "worker"=>13},
    {"status"=>"passed", "elapsed_time"=>23, "worker"=>15}
]}

$unwind之后的结果:

{"_id"=>"1867930", "tests"=>{"status"=>"passed", "elapsed_time"=>26, "worker"=>11}}
{"_id"=>"1867930", "tests"=>{"status"=>"passed", "elapsed_time"=>34, "worker"=>13}}
{"_id"=>"1867930", "tests"=>{"status"=>"passed", "elapsed_time"=>23, "worker"=>15}}

如何应用另一个操作将每个文档中的tests 键的值提升一个级别(即消除从$unwind 创建的重复的tests 键)以获得以下结果?

{"_id"=>"1867930", "status"=>"passed", "elapsed_time"=>26, "worker"=>11}
{"_id"=>"1867930", "status"=>"passed", "elapsed_time"=>34, "worker"=>13}
{"_id"=>"1867930", "status"=>"passed", "elapsed_time"=>23, "worker"=>15}

请注意,这不是重命名 tests 键,而是将 tests 的值向上移动并与父哈希合并。

【问题讨论】:

  • 重复?这与重复有什么关系?当然,您要问的只是如何将 "tests.status" 等变成 "status"。这就是您要问的对吗?只是重命名键。
  • @BlakesSeven 不,这不是重命名,而是移动 tests 的值并将其合并到父级中。
  • 是的,它正在重命名。正如链接副本上的答案所做的那样,正如此处添加的答案是该响应的副本一样。这就是你这样做的方式。通过对 mapReduce 的 JavaScript 操作,您可以做一些更通用的事情,例如添加到父级。但是您的问题和其他问题一样是关于聚合框架的。

标签: mongodb aggregation-framework


【解决方案1】:

尝试通过$project进行操作

db.collection.aggregate([
  {$unwind: '$tests'}, 
  {$project: 
     {status: '$tests.status', 
      elapsed_time: '$tests.elapse_time',
      worker: '$tests.worker'}}
]);

或者如下用光标forEach打印数据格式

db.collection.find({ "tests": {"$exists": 1 }}).forEach(
   function(doc){
      for (var i in doc.tests){
         doc.tests[i]._id = doc._id; 
         printjson(doc.tests[i]);
      }
   });

【讨论】:

  • 谢谢,这会起作用,但是有没有更通用的方法来做到这一点,而不必投影每一个键?真实数据(未在问题中显示)在 tests 哈希中具有相当多的键。
  • @KenLiu,也许您可​​以尝试使用cursor forEach 来完成它,如我的回答所示。
猜你喜欢
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多