2016-08-16 117 views
1

我在同一个集合中有多个文档。这是前两个文件:将子文档添加到同一文档中的数组中

/* 1 */ 
{ 
    "_id" : ObjectId("57b21ba6770fbe3753ddfb6f"), 
    "activeDateTime" : "11/5/2001", 
    "enabled" : 0, 
    "regionDescRefId" : ObjectId("5591bdbc807504cd138c9f38"), 
    "patientType" : [ 
     ObjectId("5500744ee4b09a58a08b72b5") 
    ], 
    "allergenWells" : [ 
     { 
      "allergenRefId" : 9, 
      "column" : 1, 
      "row" : 1 
     } 
    ] 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("57b21ba6770fbe3753ddfb70"), 
    "activeDateTime" : "11/5/2001", 
    "enabled" : 0, 
    "regionDescRefId" : ObjectId("5591bdbc807504cd138c9f38"), 
    "patientType" : [ 
     ObjectId("5500744ee4b09a58a08b72b5") 
    ], 
    "allergenWells" : [ 
     { 
      "allergenRefId" : 11, 
      "column" : 2, 
      "row" : 1 
     } 
    ] 
} 

我想从文件#2 allergenWells阵列和字段值,并将它们放到文档#1,使它看起来像这样:

/* 1 */ 
    { 
     "_id" : ObjectId("57b21ba6770fbe3753ddfb6f"), 
     "activeDateTime" : "11/5/2001", 
     "enabled" : 0, 
     "regionDescRefId" : ObjectId("5591bdbc807504cd138c9f38"), 
     "patientType" : [ 
      ObjectId("5500744ee4b09a58a08b72b5") 
     ], 
     "allergenWells" : [ 
      { 
       "allergenRefId" : 9, 
       "column" : 1, 
       "row" : 1 
      }, 
      { 
       "allergenRefId" : 11, 
       "column" : 2, 
       "row" : 1 
      } 
     ] 
    } 

所以最终过敏原威尔斯阵列将会增长。有任何想法吗?我对MongoDB很陌生,所以任何可以提供的帮助将非常感谢!

+1

会发生什么来记录#2?此操作后您是否想要更新集合,或者您只需要返回具有上述结果的文档? – chridam

+0

文档#2将会消失,其他文档将被添加(文档#3,文档#4等)因此,同一个集合中会有多个文档,我想将allergenWells字段和值添加到文档#1的变应原井阵列。我也在使用v2.6 –

+0

我的答案是否能解决您的问题? – chridam

回答

0

有几种方法可以解决这个问题。第一个是通过聚合框架的方式。这是您希望汇总文档而不更新集合的结果。

在这种情况下,你要运行聚集操作的$unwind管道包括扁平化allergenWells数组以后使用$group管道聚集。这允许您使用不同的键将文档分组,并使用运算符创建合并的数组。

请看下面的例子:

db.collection.aggregate([ 
    { "$unwind": "$allergenWells" }, 
    { 
     "$group": { 
      "_id": { 
       "activeDateTime": "$activeDateTime", 
       "enabled": "$enabled", 
       "regionDescRefId": "$regionDescRefId", 
       "patientType": "$patientType" 
      }, 
      "id": { "$min": "$_id" }, 
      "allergenWells": { "$addToSet": "$allergenWells" } 
     } 
    }, 
    { 
     "$project": { 
      "_id": "$id", 
      "activeDateTime": "$_id.activeDateTime", 
      "enabled": "$_id.enabled", 
      "regionDescRefId": "$_id.regionDescRefId", 
      "patientType": "$_id.patientType", 
      "allergenWells": 1 
     } 
    } 
]) 

样本输出

/* 1 */ 
{ 
    "_id" : ObjectId("57b21ba6770fbe3753ddfb6f"), 
    "allergenWells" : [ 
     { 
      "allergenRefId" : 11, 
      "column" : 2, 
      "row" : 1 
     }, 
     { 
      "allergenRefId" : 9, 
      "column" : 1, 
      "row" : 1 
     } 
    ], 
    "activeDateTime" : "11/5/2001", 
    "enabled" : 0, 
    "regionDescRefId" : ObjectId("5591bdbc807504cd138c9f38"), 
    "patientType" : [ 
     ObjectId("5500744ee4b09a58a08b72b5") 
    ] 
} 

然而,与上述方法一定的局限性尤其是当你打算具有allergenWells阵列越来越大,并最终导致文件大小超过16MB,或使用过多的系统内存。 在客户端而不是数据库服务器上进行内存数组合并可能会更具可扩展性。


当您想通过合并两个文档并删除其他文件来更新集合时,另一种方法是理想的。这不能做原子化,因为你需要循环虽然从上面的结果, 首先查询文档,找出你想要的$set然后更新文档使用来自聚合的值作为匹配过滤器请确保您没有在两者之间获得并发更新,并使用remove命令删除其他文档。

以下示例显示了这一概念:

db.collection.aggregate([ 
    { "$unwind": "$allergenWells" }, 
    { 
     "$group": { 
      "_id": { 
       "activeDateTime": "$activeDateTime", 
       "enabled": "$enabled", 
       "regionDescRefId": "$regionDescRefId", 
       "patientType": "$patientType" 
      }, 
      "id": { "$min": "$_id" }, 
      "allergenWells": { "$addToSet": "$allergenWells" }, 
      "duplicates": { "$addToSet": "$_id" } 
     } 
    }, 
    { 
     "$project": { 
      "_id": "$id", 
      "allergenWells": 1, 
      "dupes": { "$setDifference": ["$duplicates", ["$id"]] } 
     } 
    } 
]).forEach(function(doc){ 
    db.collection.update(
     { "_id": doc._id }, 
     { "$set": { "allergenWells": doc.allergenWells } } 
    ); // update allergenWells array 
    db.collection.remove({ "_id": { "$in": doc.dupes } }) // delete other docs 
}) 
+1

嘿chridam。感谢您的答复。第二种方法是我在寻找的。只是我需要解决问题所需的“推动力”。你太棒了! –

+0

@SamTheMan不用担心,很高兴能有所帮助 – chridam

0

可以使用MongoDB的

$push

在你的情况下,它看起来就像这样。

db.collection.update({ 
    patientType: <mypatientId> 
}, { 
    $push: { 
    allergenWells: { 
     $each: { 
     "allergenRefId" : 11, 
     "column" : 2, 
     "row" : 1 
     } 
    } 
    } 
}); 
相关问题