2017-05-16 2 views
0

私はnodejsコントローラでは非常にloooong集計があります。nodejsコントローラ内のMongoDB集約を動的に操作する方法は?

agentSaleModel.aggregate([ 
    { 
     $match: { 
      $and: 
      [{ 
       _id: { $in: req.body.propertyID }, 
       active : true 
      }] 
     } 
    }, etc.... 

を私は[「property01」、「property02」]などのような私req.body.propertyID の要素を得たとき、それは素晴らしい作品...

私の問題は、req.body.propertyIDに何もないときにも集約が機能したいということです。 (空白のとき) - すべてのレコードを取得します。

これは動作しません:

agentSaleModel.aggregate([ 
    { 
     $match: { 
      $and: 
      [{ 
       _id: { $in: '' }, 
       active : true 
      }] 
     } 
    }, etc.... 

そうではなく、ほぼ同じコードの2つの巨大なセットで「あれば」やって:

if (req.body.propertyID) { 
    ...the entire aggregate... 
} else { 
    ...the entire aggregate minus the _id: { $in: req.body.propertyID },... 
} 

これを行うには、よりスマートな方法はありますか?

解決策!

if(!req.body.properyID){ 
    req.body.propertyID = [ ".*" ]; 
} 
agentSaleModel.aggregate([ 
{ 
    $match: { 
     $and: 
     [{ 
      _id: { $in: req.body.propertyID }, 
      active : true 
     }] 
    } 
}, etc.... 

しかし、これは遅いかもしれません:のようにあなたも、正規表現を使用することができ

let query = [ 
    { 
     $match: { 
      $and: 
      [{ 
       active : true 
      }] 
     } 
    }]; 
if(req.body.propertyID) { 
    query[0]["$match"]["$and"][0]["_id"] = { $in: req.body.propertyID }; 
} 
agentSaleModel.aggregate(query, ...) 

:FluffyNightsのおかげで:)

if (req.body.propertyID!='') { 
    var matchStr = { 
     $match: { 
      $and: 
      [{ 
       _id: { $in: req.body.propertyID }, 
       active : true 
      }] 
     } 
    } 
} else { 
    var matchStr = { 
     $match: { 
       active : true 
     } 
    } 
} 
agentSaleModel.aggregate([ matchStr, etc..... (rest of pipeline) 

答えて

1

あなたはこのようにそれを行うことができます。 $ inにnullを渡すと、あなたが望むように動作するかどうかわからないので、試してみてください。

+0

はい!!!あなたの提案は実際に働いた! - 私はあなたがそれを見ることができるように質問に私の最終的な解決策を掲載させてください。どうもありがとうございます。私は本当にあなたがオブジェクトを構築し、大きな集合体に注入することができないことを本当に理解していません:) – torbenrudgaard

1

実行前にクエリを作成しようとするとどうでしょうか。

たとえば、

var query = req.body.propertyID ? { $and: [{_id: { $in: req.body.propertyID }, active : true}]} : {active : true}

agentSaleModel.aggregate([ 
{ 
    $match: query 
}, etc.... 

この情報がお役に立てば幸いです。ここで

+0

それはあまりにも働いて、非常にシンプルでエレガントです。ありがとうMykola !! – torbenrudgaard

1

computed property namesを使用して、インラインソリューションです:

$match: { 
    $and: [ 
    { 
     _id: { [ req.body.propertyID ? '$in' : '$exists' ] : req.body.propertyID || true }, 
     active: true, 
    }, 
    ], 
} 

req.body.propertyIDが存在する場合、クエリは次のようになります。

_id : { $in : req.body.propertyID } 

ない場合:

_id : { $exists : true } 

EDIT:これはまた、意志許可する明示的にすべての文書に一致させたい場合は、と"ALL"を等しくしてください:

let selectAll = ! req.body.propertyID || req.body.propertyID === 'ALL'; 
const query = { 
    $match: { 
    $and: [ 
     { 
     _id: { [ selectAll ? '$exists' : '$in' ] : selectAll || req.body.propertyID }, 
     active: true, 
     }, 
    ], 
    }, 
}; 
+0

OK Robertklep - これはまだ簡単な解決策です:-)ありがとう! – torbenrudgaard

+0

私はreq.body.propertyIDの質問があります。本当。 'if(req.body.propertyID!= 'ALL' && req.body.propertyID!= '')のようなものがあれば、それをあなたのone-linerにどのように書きますか? – torbenrudgaard

+1

@torbenrudgaard編集を参照してください。あなたはそのすべてを1つのライナーに置くことができますが、あまり明確ではないので、別のブール変数を使用することをお勧めします。 – robertklep

関連する問題