2016-04-11 7 views
2

私のMongoDBスキーマのサンプルをサブ文書のフィールドの発生を数えるには、挿入時間がServerTimeなり、Docは1時間ごとに挿入され、以下のとおりです。MongoDBのクエリと

{ 
    "_id" : ObjectId("5709fd69c1aa400008ff66da"), 
    Doc: { 
     total: 245, 
     sub-docs: [ 
      { 
       accessedURL: "www.example.com", 
       User:{ 
        name: "John" 
       } 
       Time:{ 
        ServerTime: "2016-03-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:43:41.296+0800" 
        LastAccessTime: "2016-03-30T15:33:41.296+0800" 
       } 

      }, 
      { 
       accessedURL: "www.123.com", 
       User:{ 
        name: "John" 
       } 
       Time:{ 
        ServerTime: "2016-03-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:40:41.296+0800" 
        LastAccessTime: "2016-03-30T15:23:41.296+0800" 
       } 

      }, 
      { 
       accessedURL: "www.example.com", 
       User:{ 
        name: "Eric" 
       } 
       Time:{ 
        ServerTime: "2016-03-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:43:41.296+0800" 
        LastAccessTime: "2016-03-30T15:33:41.296+0800" 
       } 

      }, 
      ... # 245 sub-docs in the array 
     ] 
    } 
} 
... # more Docs 
... 

NPTEServerTimeは、私はで各User.nameアクセスしたURLの数を照会するDoc

内のすべてのsub-docsため同じになります文書及びこれらDocDoc.sub-docs.ServerTimeに基づいた時間枠の間に入る必要があり、最終的な出力は、それを達成するためにどのように

{ 
    ServerTime: "2016-03-30T15:45:41.296+0000", 
    sub-docs: { 
     John: 3, 
     Eric: 4, 
     ... 
    } 
} 
{ 
    ServerTime: "2016-03-30T16:45:41.296+0000", 
    sub-docs: { 
     John: 1, 
     Eric: 2, 
     ... 
    } 
} 
... 
... 

でしょうか?

+0

ServerTimeをドキュメントレベルで使用していれば、簡単に集約を使用することができます。なぜなら、常に同じであれば、各サブドキュメントに埋め込むのはなぜですか? –

答えて

0

あなたがコンマ

db.test.insert({ 
    Doc: { 
     total: 245, 
     sub_docs: [ 
      { 
       accessedURL: "www.example.com", 
       User:{ 
        name: "John" 
       }, 
       Time:{ 
        ServerTime: "2016-03-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:43:41.296+0800", 
        LastAccessTime: "2016-03-30T15:33:41.296+0800" 
       } 
      }, 
      { 
       accessedURL: "www.123.com", 
       User:{ 
        name: "John" 
       }, 
       Time:{ 
        ServerTime: "2016-04-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:40:41.296+0800", 
        LastAccessTime: "2016-03-30T15:23:41.296+0800" 
       } 
      }, 
      { 
       accessedURL: "www.example.com", 
       User:{ 
        name: "Eric" 
       }, 
       Time:{ 
        ServerTime: "2016-03-30T15:45:41.296+0000", 
        FirstAccessTime: "2016-03-30T12:43:41.296+0800", 
        LastAccessTime: "2016-03-30T15:33:41.296+0800" 
       } 
      } 
     ] 
    } 
}); 

といくつかの問題を持っているように私は、私は、このアグリゲーションパイプラインを作成するには、次のテストデータを使用していました。

db.test.aggregate([ 
    { $unwind : "$Doc.sub_docs" }, 
    { $group : { "_id" : "$Doc.sub_docs.Time.ServerTime" , sub_doc : { $push : "$Doc.sub_docs.User.name" } } }, 
    { $unwind : "$sub_doc" }, 
    { $group : { "_id" : { "time" : "$_id" , "user" : "$sub_doc"} , sum : {$sum : 1}} }, 
    { $project : { "ServerTime": "$_id.time", sub_docs : { user : "$_id.user" , visits : "$sum" }, _id : 0 }}, 
    { $group : { "_id" : "$ServerTime" , sub_doc : { $push : "$sub_docs" } } } 
]); 

結果はあなたが探しているまさにではなく、同じ内容

{ "_id" : "2016-04-30T15:45:41.296+0000", "sub_doc" : [ { "user" : "John", "visits" : 1 } ] } 
{ "_id" : "2016-03-30T15:45:41.296+0000", "sub_doc" : [ { "user" : "Eric", "visits" : 1 }, { "user" : "John", "visits" : 1 } ] } 

を持ってあなただけのだけがレコードに、この操作を使用するために最初のアンワインド前$matchの状態を追加する必要がありますあなたの日付範囲に一致します。 また、あなたがSERVERTIMEラベル

{ $project : { "ServerTime": "$_id" , sub_doc : 1, "_id" : 0}} 

を設定するには、以下の行を追加することができ、おそらく、単純なパイプラインのことでしたが、私が今持っているもので、それが役に立てば幸い。