2016-04-11 9 views
2

Mein mongoDB Schema Probe sind wie die folgenden, die Doc jede 1 Stunde eingeführt wird, wird die eingelegte Zeit die ServerTime sein:MongoDB Abfrage und zählen Auftreten des Unterdokumentenfeld

{ 
    "_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 
... 

NPTE: Die ServerTime wird identisch für alle sub-docs im Doc

sein ich jede User.name zugegriffen URL Zahl in derabfragen möchtenDokument und Diejenigen Doc sollte auf der Doc.sub-docs.ServerTime Basis zwischen einem Zeitrahmen fallen in, wird die endgültige Ausgabe

sein
{ 
    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, 
     ... 
    } 
} 
... 
... 

Wie das erreichen?

+0

Sie könnten Aggregation leicht verwenden, wenn Sie die ServerTime auf Doc-Ebene hatten ... Warum sollte es auf jedem Subdoc eingebettet werden, wenn es immer gleich ist? –

Antwort

0

ich verwendet, um die folgenden Testdaten wie Sie einige Probleme mit Komma haben

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" 
       } 
      } 
     ] 
    } 
}); 

ich diese Aggregation Pipeline erstellen.

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" } } } 
]); 

Das Ergebnis ist nicht genau, was Sie suchen, aber den gleichen Inhalt haben

{ "_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 } ] } 

Sie müssen nur einen $match Zustand vor dem ersten Abroll hinzufügen diesen Vorgang in den Aufzeichnungen nur verwenden, die Passen Sie Ihren Datumsbereich an. Auch könnten Sie die folgende Zeile hinzufügen Server Label

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

Wahrscheinlich eine einfache Pipeline könnte zu setzen, sondern das, was ich jetzt haben, hoffen, dass es hilft.