2016-11-15 2 views
0

mongoDBとnodeJSを使ってオンラインテストアプリケーションを構築したい。管理者がユーザーテストの履歴を見ることができる機能があります(日付フィルタオプション付き)。日付操作insedeと配列(集約)

テスト結果配列にadminで指定された日付が含まれているユーザーのみを表示する場合は、クエリを実行する方法。

日付フィルタはscheduledAt.startTimeの日、月、年に基づいており、これを達成するには集約フレームワークを使用する必要があります。

{ 
    "_id" : ObjectId("582a7b315c57b9164cac3295"), 
    "username" : "[email protected]", 
    "displayName" : "lalala", 
    "testResults" : [ 
     { 
      "applyAs" : [ 
       "finance" 
      ], 
      "scheduledAt" : { 
       "endTime" : ISODate("2016-11-15T16:00:00.000Z"), 
       "startTime" : ISODate("2016-11-15T01:00:00.000Z") 
      }, 
      "results" : [ 
       ObjectId("582a7b3e5c57b9164cac3299"), 
       ObjectId("582a7cc25c57b9164cac329d") 
      ], 
      "_id" : ObjectId("582a7b3e5c57b9164cac3296") 
     }, 
     { 
      ..... 
     } 
    ], 
    "password" : "andi", 
} 

testResultsを文書:

{ 
    "_id" : ObjectId("582a7cc25c57b9164cac329d"), 
    "testCategory" : "english", 
    "testVersion" : "EAX", 
    "testTakenTime" : ISODate("2016-11-15T03:10:58.623Z"), 
    "score" : 2, 
    "userAnswer" : [ 
     { 
      "answer" : 1, 
      "problemId" : ObjectId("581ff74002bb1218f87f3fab") 
     }, 
     { 
      "answer" : 0, 
      "problemId" : ObjectId("581ff78202bb1218f87f3fac") 
     }, 
     { 
      "answer" : 0, 
      "problemId" : ObjectId("581ff7ca02bb1218f87f3fad") 
     } 
    ], 
    "__v" : 0 
} 

私が今まで試してみましたが、以下のようなものです

はのは、私は、ユーザーが以下のように文書化してきたとしましょう。私が総文書を数えたい場合は、集計フレームワークのどの部分を変更すべきですか。以下のクエリでは、返されるドキュメント全体ではなく、グループごとにtotalDataが合計されるためです。

User 
     .aggregate([ 
     { 
      $unwind: '$testResults' 
     }, 
     { 
      $project: { 
      '_id': 1, 
      'displayName': 1, 
      'testResults': 1, 
      'dayOfTest': { $dayOfMonth: '$testResults.scheduledAt.startTime' }, 
      'monthOfTest': { $month: '$testResults.scheduledAt.startTime' }, 
      'yearOfTest': { $year: '$testResults.scheduledAt.startTime' } 
      } 
     }, 
     { 
      $match: { 
      dayOfTest: date.getDate(), 
      monthOfTest: date.getMonth() + 1, 
      yearOfTest: date.getFullYear() 
      } 
     }, 
     { 
      $group: { 
      _id: {id: '$_id', displayName: '$displayName'}, 
      testResults: { 
       $push: '$testResults' 
      }, 
      totalData: { 
       $sum: 1 
      } 
      } 
     }, 
     ]) 
     .then(function(result) { 
     res.send(result); 
     }) 
     .catch(function(err) { 
     console.error(err); 
     next(err); 
     }); 
+0

これまでに試したことを追加できますか? – Veeram

+0

@Veeramこんにちは、私はすでに私のexplainationを更新します。それを確認してください:) – Kim

+0

あなたは別のグループステージを追加できます。すべてのユーザー文書の合計数を取得し、前のグループの表示、グループ数、およびテスト結果をプッシュし、オプションの最終プロジェクト段階を追加してレスポンスをフォーマットすることができます。あなたが期待した反応を追加することができますこの場合、私は試してみることができます。 – Veeram

答えて

0

このようなことを試すことができます。渡された日付に一致する結果要素がある場合、テスト結果を保持するプロジェクト段階を追加しました。これをパイプラインの最初のステップとして追加し、必要な方法でグループ化ステージを追加できます。

$ mapは、渡された日付と開始日の間の等しい比較を各テスト結果要素に適用し、true値とfalse値を持つ配列を生成します。 $ anyElementTrueはこの配列を検査し、配列に少なくとも1つの真の値がある場合にのみtrueを返します。マッチした値がtrueの要素だけを含むようにステージにマッチさせる。

aggregate([{ 
    "$project": { 
     "_id": 1, 
     "displayName":1, 
     "testResults": 1, 
     "matched": { 
      "$anyElementTrue": { 
       "$map": { 
        "input": "$testResults", 
        "as": "result", 
        "in": { 
         "$eq": [{ $dateToString: { format: "%Y-%m-%d", date: '$$result.scheduledAt.startTime' } }, '2016-11-15'] 
        } 
       } 
      } 
     } 
    } 
}, { 
    "$match": { 
     "matched": true 
    } 
}]) 

オルタナティブバージョン:上記バージョンへ

似ていますが、これは一つにプロジェクトと一致段階の両方を兼ね備えています。 $ condと$ redactが一致するアカウントがあり、一致が見つかった場合は完全なツリーが保持されます。そうでない場合は破棄されます。

aggregate([{ 
    "$redact": { 
     "$cond": [{ 
       "$anyElementTrue": { 
        "$map": { 
         "input": "$testResults", 
         "as": "result", 
         "in": { 
          "$eq": [{ 
           $dateToString: { 
            format: "%Y-%m-%d", 
            date: '$$result.scheduledAt.startTime' 
           } 
          }, '2016-11-15'] 
         } 
        } 
       } 
      }, 
      "$$KEEP", 
      "$$PRUNE" 
     ] 
    } 
}]) 
+0

クールな男、私はこの答えが完全に動作すると思います。たぶん私はあなたの解答を最初に学ぶでしょう。なぜならあなたの解法には私がまだ分かっていない多くの奇妙な構文や演算子があるからです。 – Kim

+0

申し訳ありません。私は代わりのバージョンを追加したばかりでなく、各オペレータが何をしているのかの説明を追加しました。お役に立てれば。 – Veeram

+0

いいえ、申し訳ありませんVeeramと言ってください。私はそういう意味ではありません。私はあなたの答えをまず学ぶつもりです。なぜなら、私はまだmongoDBの新機能なので、多くの構文が私にとって奇妙に見えます。 あなたのソリューションは、mongoDBのドキュメントに含まれている多くの機能の実装を知る上で本当に役に立ちます。実際の実装と各フィーチャー/演算子の結果を知っているので、ドキュメントを読むと本当に助けになります。 代替バージョンのおかげでBtwは本当にmongoDBをより深く学ぶのに役立ちます。 – Kim