2016-11-15 1 views
1

私はかなり複雑なクエリを作成しようとしています。最終的に私はそれをすべて手作業で書く必要を避けようとしています。私がしようとしているのは、動的なフィールドを取得し、各フィールドにフィールドが存在するかどうか、そしてそれが更新されているかどうかを確認することです。問題は、フィールドが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' 
     } 
    ] 
} 

:ここ

は、典型的なオブジェクトがどのように見えるかです。最終的な目標は、1つのクエリでそれを行うことです。私は基本レベルで1つのフィールドで動作させましたが、組み込みドキュメントでも動的名に一致するすべてのフィールドで動作させる方法があるかどうか疑問に思っていました。

 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); 

私は基本的にすべては、動的にクエリを構築し、Mongoの集約にそれを渡すと、それはチャンピオンのようにそれを読んでいました。

関連する問題