2017-01-05 13 views
1

特定の年の収入を返すクエリを作成したいと思います。私のスキーマは、このようなものです:マングース条件付きクエリ - like文の場合

export const IncomeSchema = new mongoose.Schema({ 
name: { type: String, required: true }, 
amount: { type: Number, required: true }, 
amountAfterTax: { type: Number, required: false }, 
dateFrom: { 
    month: Number, 
    year: Number 
}, 
dateTo: { 
    month: Number, 
    year: Number 
}, 
isMonthly: { type: Boolean, required: true }, 
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } 
}, { toJSON: { virtuals: true } }); 

// somehow use the req.params.year 
return DB.Incomes.find({ userId: req.user).exec().then(incomes => { 
let incomesForMonth = incomes.filter(income => !income.isMonthly ? (income.dateFrom.year== req.params.year) 
    : (income.dateFrom.year <= req.params.year && income.dateTo.year >= req.params.year) 
}); 
事は、私は、クエリがそのように実行したいということです

: を - 収入はisMonthlyそして今年はdateFrom.year 等しくなるように持っている場合 - もし収入isMonthlyその後、年! dateFrom.yearとdateTo.yearの間にある必要があります

これまで私はdbからすべてを返していましたが、これは最大の解決策ではありません。 SQL Serverでは、CASE WHENステートメントを使用します。私はモンゴースで何が使えますか?

+0

あなたはMongooseとMongoDB Serverのバージョンを教えてください。あなたのサーバ上のMongoDBのバージョンに依存する解決策を提案したいと思います。 'MongoDB Server 3.4.x:mongoose> = 4.7.3' – chridam

+0

現在、私はmongooseを' 4.3.6'で使用しています。 mlab.comで、私はそれが '3.2.x'で最大だと思います。 –

答えて

1

残念ながらあなたの現在のバージョンでは、case文/式を模倣するネイティブMongoDB演算子を持つperform-antソリューションは考えられません。

しかし、MongoDBのサーバー3.4とマングース> = 4.7.3のために、あなたは特に新しい$addFieldsステージと、このようなクエリの$switchオペレータを集約フレームワークを使用することができます解決策があります。

$addFieldsステージは、明示的に入力文書内のすべての既存のフィールドを指定し、文書に新しいフィールドを追加し$project段階に相当します。あなたのケースでは、それはあなたの$matchクエリで使用されている新しいフィールドフィールドを作成する必要があります。

$switch演算子は、一連のケース式を評価します。真と評価される式が見つかると、 $switchが実行され、制御フローからブレークします。

移入テストコレクション:

year = 2016; 
db.test.aggregate([ 
    { 
     "$addFields": { 
      "incomesForMonth": { 
       "$switch": { 
        "branches": [ 
         { 
          "case": "$isMonthly", /* same as "case": { "$eq": [ "$isMonthly", true ] }, */ 
          "then": { "$eq": [ "$dateFrom.year", year ] } 
         }, 
         { 
          "case": { "$eq": [ "$isMonthly", false ] }, 
          "then": { 
           "$and": [ 
            { "$lte": [ "$dateFrom.year", year ] }, 
            { "$gte": [ "$dateTo.year", year ] } 
           ] 
          } 
         } 
        ] 
       } 
      } 
     } 
    }, 
    { "$match": { "incomesForMonth": true } } 
]) 

サンプル出力

db.test.insert([ 
    { 
     name: "foo", 
     amount: 4, 
     amountAfterTax: 3.2, 
     dateFrom: { 
      month: 11, 
      year: 2016 
     }, 
     dateTo: { 
      month: 2, 
      year: 2017 
     }, 
     isMonthly: true, 
     userId: ObjectId("5864b49ab5a589b63ee298e8") 
    }, 
     { 
     name: "test", 
     amount: 547.74, 
     amountAfterTax: 507.15, 
     dateFrom: { 
      month: 4, 
      year: 2016 
     }, 
     dateTo: { 
      month: 4, 
      year: 2017 
     }, 
     isMonthly: true, 
     userId: ObjectId("5864b49ab5a589b63ee298e8") 
    }, 
     { 
     name: "bar", 
     amount: 56, 
     amountAfterTax: 47.54, 
     dateFrom: { 
      month: 5, 
      year: 2016 
     }, 
     dateTo: { 
      month: 7, 
      year: 2016 
     }, 
     isMonthly: false, 
     userId: ObjectId("5864b49ab5a589b63ee298e8") 
    } 
]) 

実行集計クエリ

のは、モンゴシェルの例でこれを証明してみましょう

/* 1 */ 
{ 
    "_id" : ObjectId("586ea7bafedfbcfd0ed15f9a"), 
    "name" : "foo", 
    "amount" : 4.0, 
    "amountAfterTax" : 3.2, 
    "dateFrom" : { 
     "month" : 11.0, 
     "year" : 2016.0 
    }, 
    "dateTo" : { 
     "month" : 2.0, 
     "year" : 2017.0 
    }, 
    "isMonthly" : true, 
    "userId" : ObjectId("5864b49ab5a589b63ee298e8"), 
    "incomesForMonth" : true 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("586ea7bafedfbcfd0ed15f9b"), 
    "name" : "test", 
    "amount" : 547.74, 
    "amountAfterTax" : 507.15, 
    "dateFrom" : { 
     "month" : 4.0, 
     "year" : 2016.0 
    }, 
    "dateTo" : { 
     "month" : 4.0, 
     "year" : 2017.0 
    }, 
    "isMonthly" : true, 
    "userId" : ObjectId("5864b49ab5a589b63ee298e8"), 
    "incomesForMonth" : true 
} 

/* 3 */ 
{ 
    "_id" : ObjectId("586ea7bafedfbcfd0ed15f9c"), 
    "name" : "bar", 
    "amount" : 56.0, 
    "amountAfterTax" : 47.54, 
    "dateFrom" : { 
     "month" : 5.0, 
     "year" : 2016.0 
    }, 
    "dateTo" : { 
     "month" : 7.0, 
     "year" : 2016.0 
    }, 
    "isMonthly" : false, 
    "userId" : ObjectId("5864b49ab5a589b63ee298e8"), 
    "incomesForMonth" : true 
} 
+1

私はDBのアップデートを考えています。ありがとう! –