mongo 是不是提供解构大型数据集的文档数组的功能?

Posted

技术标签:

【中文标题】mongo 是不是提供解构大型数据集的文档数组的功能?【英文标题】:Does mongo provide functionality for deconstructing document arrays for large datasets?mongo 是否提供解构大型数据集的文档数组的功能? 【发布时间】:2015-12-23 14:48:01 【问题描述】:

类似于 map/reduce 但反过来。 mongo 是否有重新格式化数据的方法。我有一个以下格式的集合。

 
  "token-id" : "LKJ8_lkjsd"
    "data": [
               "views":100, "Date": "2015-01-01",
               "views":200, "Date": "2015-01-02",
               "views":300, "Date": "2015-01-03",
               "views":300, "Date": "2015-01-03"
            ]
  

我想将整个集合处理成一种新格式。其中每个时间序列数据点都是映射到 ID 的文档,希望使用一些类似于 map reduce 的固有 mongo 功能。如果没有;我很欣赏我们可以做到这一点的策略。


   "token-id" : "LKJ8_lkjsd", "views": 100, "Date" : "2015-01-01",
   "token-id" : "LKJ8_lkjsd", "views": 200, "Date" : "2015-01-01",
   "token-id" : "LKJ8_lkjsd", "views": 300, "Date" : "2015-01-01"

【问题讨论】:

也许这有帮助:***.com/questions/13281733/… 【参考方案1】:

聚合命令可以将结果作为游标返回或存储 生成一个不受大小限制的集合。这 db.collection.aggregate() 返回一个游标,可以返回结果集 任何大小。

 var result = db.test.aggregate( [  $unwind : "$data" , $project: _id:0, "token-id":1, "data":1])

    for(result.hasNext())
     db.collection.insert(result.next());
    

【讨论】:

【参考方案2】:

您需要来自聚合管道的$unwind see mongodb documentation

在你的情况下,代码是

db.yourcollection.aggregate( [  $unwind : "$data"  ] )

unwind 不会自行将文档插入到新集合中

你可以使用

> db.test.aggregate( [  $unwind : "$data" , $project: _id:0, "token-id":1, "data":1, $out: "another" ] )
> db.another.find()

在第一行你需要禁止_id,因为在$unwind之后你会得到4个具有相同_id的文档(因此它们不能被插入) 如果没有显式的_id,则会自动生成新值

这是我为您的示例得到的输出

 "_id" : ObjectId("560599b1699289a5b754fab9"), "token-id" : "LKJ8_lkjsd", "data" :  "views" : 100, "Date" : "2015-01-01"  
 "_id" : ObjectId("560599b1699289a5b754faba"), "token-id" : "LKJ8_lkjsd", "data" :  "views" : 200, "Date" : "2015-01-02"  
 "_id" : ObjectId("560599b1699289a5b754fabb"), "token-id" : "LKJ8_lkjsd", "data" :  "views" : 300, "Date" : "2015-01-03"  
 "_id" : ObjectId("560599b1699289a5b754fabc"), "token-id" : "LKJ8_lkjsd", "data" :  "views" : 300, "Date" : "2015-01-03"  

【讨论】:

这具有功能,但会产生单个文档结果而不是新集合。另外,mongo为这个操作分配的大小只有16mb。我的数据库是 10 gbs【参考方案3】:

根据您对大型数据集的问题,$unwind 会导致性能下降,这种情况下的查询您应该在聚合中使用 $map 来处理data 的数组,如下所示:

db.collection.aggregate(
"$project": 
    "result": 
        "$map": 
            "input": "$data",
            "as": "el",
            "in": 
                "token-id": "$token-id",
                "views": "$$el.views",
                "Date": "$$el.Date"
            
        
    
 
).pretty()

【讨论】:

不幸的是,这只会重新映射每个项目,不会为每个数据记录创建额外的文档 @Dap 我不明白你期望的输出,但也许你应该unwind result 然后你会得到单独的文件。 感谢您的回复。是的,没有限制的放松是我正在寻找的,除了它的 16mb 限制 @Dap 看到你得到了答案,但仍然存在问题,你展开数据并迭代它老化以插入新集合,所以更好的方法是展开并在聚合中使用 $out

以上是关于mongo 是不是提供解构大型数据集的文档数组的功能?的主要内容,如果未能解决你的问题,请参考以下文章

Mongo 检查文档是不是已经存在

mongo 介绍

对于大型数据集的查询,日期类型是不是比日期时间更高效?

确定传入的 CSV 数据和现有的大型数据集 Mongo 集合之间的差异

Firebase 与大型数据集的性能

mongo spark 大型集合的推断模式