首页 > 解决方案 > 如何在任意深度更新 MongoDB 字段名称

问题描述

我目前正在处理许多不同的文档,这些文档包含嵌套在不同深度的地址,我需要将其中的数据迁移到不同格式的地址。我想创建一个可以用于所有收藏的请求。下面是一个文档示例:

{
"foo": 1,
"bar": 2,
"address": {
    "streetNumber": "23"
    "streetType": "rue",
    "streetName": "du stack"
},
"stuff": {
    "baz": 3,
    "gobble": {
        "wibble",
        "address": {
            "streetNumber": "23"
            "streetType": "rue",
            "streetName": "du stack"
        }                
    },
    "plugh": {
        "plove": {
            "address": {
                "streetNumber": "23"
                "streetType": "rue",
                "streetName": "du stack"
            } 
     }
}

在本文档中,我想合并 streetType 和 streetName,然后删除 streetType 字段,使地址看起来像这样:

"address": {
        "streetNumber": "23"
        "streetName": "rue du stack"
},  

我开始处理 mongo 请求,但我对此仍然很陌生。我从How to find MongoDB field name at absolute depth 中获得灵感,但我知道这在这里并不适用,因为我想修改文档而不仅仅是返回它们。

db.myCollection.updateMany(
{ $where : 
  function () {
    var searchKey = "streetType";
  
    return searchInObj(this);
  
    function searchInObj(obj){                            
        for(var k in obj){       
          if(typeof obj[k] == 'object' && obj[k] !== null){
            if(searchInObj(obj[k])){
               obj[k].streetName = obj[k].streetType + ' ' + obj[k].streetName;
               delete obj[k].streetType;
               return true;
            }
          } else {
            if(k == searchKey){
              return true;
            }
          }          
        }                         
        return false;
  }
}}, 
{ $unset : { streetType: ""} }
)

所以是的,它不起作用,我知道它可能看起来很错误我自己可以看到它,虽然我发现 $where 东西至少返回了正确的文档,但我不知道如何将修改应用于每次找到一个嵌套的“地址”。现在我考虑一下,它只会在它找到的第一次出现的地址处出现,并且会从函数返回,所以解决方案可能与此非常不同。任何见解将不胜感激!

标签: mongodb

解决方案


推荐阅读