2016-11-15 59 views
1

我有非常复杂的查询,我试图编写,似乎无法将我的头围绕写入它的最佳方式。最终,我试图避免必须手动全部写出来。我想要做的是采取一个动态的领域,并通过每个文件,看看这个领域是否存在,如果它确实然后更新它。问题在于该字段在文档中可能存在多次,因为它可以在嵌入式级别上存在于每个单独父文档的多个嵌入式文档中。根据匹配查询更新所有文档和嵌入文档中的字段MongoDB NodeJS

这里是一个典型的对象是什么样子:

applications: { 
    _id: 5368hss76sd9f, 
    ProgramAreaId: 1, 
    ProgramArea: 'Education', 
    StrategyId: 16, 
    Strategy: 'Graduate Program', 
    AlternateMapping: [{ 
     ProgramAreaId: 2, 
     ProgramArea: 'Private Sector', 
     StrategyId: 13, 
     Strategy: 'Higher Education Fund' 
    }], 
    Funding: [{ 
     Amount: '500000' 
     StrategyId: 16 
     Strategy: 'Graduate Program' 
     }, 
     { 
     Amount: '500000' 
     StrategyId: 13 
     Strategy: 'Higher Education Fund' 
     } 
    ] 
} 

我可能有这些,我将需要一次更新几千。最终目标是在一个查询中完成。我已经让它在基本级别的单个字段上工作,但想知道是否有办法使它适用于所有与动态名称匹配的字段,即使在嵌入式文档中也是如此。

这里是我到目前为止已经试过:

 var fieldId = obj.Type + 'Id'; //obj.Type could equal 'Strategy' or 'ProgramArea' 
    var field = obj.Type; 
    var id = 13; //This could be any number of ids and ultimately was what I want to match on. 
     var qry = { 
      $where: function() { 
       var deepIterate = function(o, value) { 
        for (var field in o) { 
         if (field == fieldId && obj[field] == value) { 
          console.log() 
          return true; 
         } 
         var found = false; 
         if (typeof o[field] === 'object') { 
          found = deepIterate(o[field], value) 
          if (found) { 
           return true; 
          } 
         } 
        } 
        return false; 
       }; 
       return deepIterate(this, id) 
      } 
     }; 

     var setQry = { $set: {} }; 
     setQry.$set[field] = obj.Name;//Field here would be 'Strategy' or 'ProgramArea' or any number of other fields I could be updateing and Name is what I want the value of that field to equal. 

     mongo.collection('applications').updateMany(qry, setQry, function(err, result) { 
      if (err) 
       callback(null); 
      else 
       callback(result); 
     }); 

上面的查询会找到我任何“应用”,它包含的字段名称相同的字段名称我要求的,它甚至会通过搜索嵌入文档以查看该字段是否存在。上述查询的问题是,它只会更新父级别上的该字段,而不是更新子级。

回答

0

所以我想我已经找到了上述代码的最佳解决方案。我创建了下面的代码来完成上面的问题,它的功能非常好!

var resultsArray = []; 
var fieldId = obj.Type + 'Id'; 
var field = obj.Type; 
if (coll == 'statuses') { 
    fieldId = "StatusId"; 
    field = "Status"; 
} 

var altmapField = 'AltMaps.' + fieldId, 
    altfundField = 'AltFunds.' + fieldId, 
    paymentField = 'Payments.' + fieldId, 
    reportField = 'Reports.' + fieldId, 
    crosswalkField = 'Crosswalk.' + fieldId, 
    regionField = 'RegionBreakdowns.' + fieldId, 
    sectorField = 'SectorBreakdowns.' + fieldId; 
var qry = []; 
qry.push({ 
    $match: { 
     $or: [{ 
     }, { 
     }, { 
     }, { 
     }, { 
     }, { 
     }, { 
     }, { 
     }] 
    } 
}); 

qry[0].$match.$or[0][fieldId] = id; 
qry[0].$match.$or[1][altmapField] = id; 
qry[0].$match.$or[2][altfundField] = id; 
qry[0].$match.$or[3][paymentField] = id; 
qry[0].$match.$or[4][reportField] = id; 
qry[0].$match.$or[5][crosswalkField] = id; 
qry[0].$match.$or[6][regionField] = id; 
qry[0].$match.$or[7][sectorField] = id; 


var cursor = mongo.collection(collectionPrefix + 'applications').aggregate(qry, { allowDiskUse: true, explain: false }, null); 

基本上我所做的就是动态地构建出一个查询,然后传递到蒙戈集合,它读取它像一个冠军。

相关问题