2016-06-15 28 views
4
{ 
    "_id" : ObjectId("576155a6cd87b68f7e6e42c9"), 
    "First_Name" : "ok", 
    "Last_Name" : "jaao", 
    "Email" : "[email protected]", 
    "Sessions" : [ 
     { 
      "Last_Login" : "Wed, Jun 14, 2016 6:48 PM", 
      "Class" : "fb", 
      "ID" : "123" 
     }, 
     { 
      "Last_Login" : "Wed, Jun 15, 2016 6:48 PM", 
      "ID" : "111", 
      "Class" : "fb" 
     } 
    ], 
    "Count" : 2 
}, 
{ 
    "_id" : ObjectId("576155ccf6d8979e7e77df27"), 
    "First_Name" : "abc", 
    "Last_Name" : "xyz", 
    "Email" : "[email protected]", 
    "Sessions" : [ 
     { 
      "Last_Login" : "Wed, Jun 15, 2016 6:49 PM", 
      "Class" : "fb", 
      "ID" : "123" 
     } 
    ], 
    "Count" : 1 
} 

これは私のJSON構造です。現在ログインしているすべてのユーザ、つまりLast_Loginの今日の日付を取得するmongoDBクエリが必要です。入れ子配列コレクションから検索するmongoDBクエリ

私はと私の出力をしたい:あなたは$elemMatchaggregateが必要になります

{ 
    "_id" : ObjectId("576155a6cd87b68f7e6e42c9"), 
    "First_Name" : "ok", 
    "Last_Name" : "jaao", 
    "Email" : "[email protected]", 
    "Sessions" : [ 
     { 
      "Last_Login" : "Wed, Jun 15, 2016 6:48 PM", 
      "ID" : "111", 
      "Class" : "fb" 
     } 
    ], 
    "Count" : 2 
}, 
{ 
    "_id" : ObjectId("576155ccf6d8979e7e77df27"), 
    "First_Name" : "abc", 
    "Last_Name" : "xyz", 
    "Email" : "[email protected]", 
    "Sessions" : [ 
     { 
      "Last_Login" : "Wed, Jun 15, 2016 6:49 PM", 
      "Class" : "fb", 
      "ID" : "123" 
     } 
    ], 
    "Count" : 1 
} 
+1

日付は効果がないかもしれ複雑なクエリが必要になります。スキーマを変更して 'Last_Login'の日付を' ISODate() 'として保存することを検討してください – chridam

+0

Last_Loginフィールドにはmoment.jsライブラリによって提供されるformat( 'llll')の形式のデータが含まれています。 ISODate()に??? –

+0

はい、上記の形式の文字列として保存するのではなく、適切なDate()型としてMongoDBに日付を格納する方が良いでしょう。 – chridam

答えて

1

db.users.aggregate([ 
    { 
     $unwind: "$Sessions" 
    }, 
    { 
     $match: { 
      "Sessions.Last_Login": { 
       $gte: ISODate("2016-06-16T00:00:00.0Z"), 
       $lt: ISODate("2016-06-17T00:00:00.0Z") 
      } 
     } 
    }, 
    { 
     $group: { 
      _id: { 
       _id: "$_id", 
       First_Name: "$First_Name", 
       Last_Name: "$Last_Name" 
      }, 
      Sessions: { 
       $push: "$Sessions" 
      } 
     } 
    }, 
    { 
     $project: { 
      _id: "$_id._id", 
      First_Name: "$_id.First_Name", 
      Last_Name: "$_id.Last_Name", 
      Sessions: "$Sessions" 
     } 
    } 
]) 

ので、クエリが実行しますこれらのステップ:_idFirst_Nameによって

  1. $unwindすべてSessions
  2. $group一緒日付範囲内の要素
  3. $match文書を、文書、Last_Name
  4. $project loへの書類元の形式のようにokです

フィールドを一部省略しましたが、$group$projectのステップで簡単に追加できます。もちろん、期間を変更する必要があります。

大きなコレクションでこのクエリのパフォーマンスが心配です。私が与えた最初のクエリを使用して、コード内で必要なセッションをフィルタリングする方が良いかもしれません。

編集:@chridamが言ったように

、このクエリが推奨されているもの、あなたがISODate()Last_Loginを変更する場合にのみ動作します。

編集2:

aggregateを使用してのみ日付範囲内Sessionsをフェッチの要求に一致するクエリを更新します。

これは古いバージョンです:そのような保存された

db.users.filter({ 
    'Sessions': { 
     '$elemMatch': { 
      'Last_Login': { 
       '$gte': ISODate("2016-06-16T00:00:00.0Z"), 
       '$lt': ISODate("2016-06-17T00:00:00.0Z") 
      } 
     } 
    } 
}) 
+0

'Last_Login'日付がOPによって文字列として与えられているので、クエリがうまくいくかどうかは分かりません。 – chridam

+0

@chridam確かに、気づかなかった。 –

+0

ISODate()は定義されていません...他の選択肢?? –

関連する問題