2017-06-09 5 views
1

Ich habe eine Anwendung, die Benutzer und ihr Verhalten in Form von Ereignissen speichert. Es gibt zwei Sammlungen, eine für die Benutzer und eine für die Ereignisse. Die Dokumente wie folgt aussehen:MongoDB: Filter mit Daten aus mehreren Sammlungen

Benutzer

{ 
    "_id" : ObjectId("593aa71e2f9d5140000bb44e"), 
    "name" : "Antonette Ortiz", 
    "country" : "France" 
} 

Ereignis

{ 
    "_id" : ObjectId("593aaa84c685604066a6a0cf"), 
    "name" : "message_sent", 
    "timestamp" : ISODate("2016-11-01T04:39:52.667Z"), 
    "user" : ObjectId("593aa728d135484002399bac"), 
    "attributes" : { 
     "str" : "plum", 
     "int" : 82 
    } 
} 

Jetzt habe ich eine Liste der Benutzer in der Lage sein wollen, nur durch ihre Attribute nicht zu holen, sondern auch in Bezug auf die Ereignisse, die sie ausgelöst haben und in Bezug auf einen bestimmten Zeitrahmen.

Eine Beispielabfrage wäre etwa so: "Alle Benutzer aus Frankreich, die innerhalb der letzten 7 Tage mindestens 3 Nachrichten gesendet haben".

Wie kann ich dies mit MongoDB erreichen, auch in Bezug auf die Leistung (wenn ich zum Beispiel mehrere Millionen Ereignisse habe)? Ist das überhaupt nur mit den beiden Sammlungen möglich, oder muss ich aggregation/map reduce verwenden? Wenn ja, wie würden Sie empfehlen, das Schema zu ändern?

+0

Entweder Aggregation mit Nachschlag, oder auf Anwendungsebene folgt. mapreduce arbeitet nur mit einer einzigen Sammlung, daher wird eine temporäre Sammlung für die Suche benötigt, die für operative Abfragen kaum geeignet ist. –

+0

Können Sie ein Beispiel für die Aggregation mithilfe von Lookup bereitstellen? Und wie würden Sie das auf der Anwendungsebene angehen? Wollen Sie die Daten anfordern und manuell zusammenführen? – benjiman

+0

https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/, zögern Sie nicht zu fragen, wenn Sie irgendwelche besonderen Probleme haben. Mit Anwendungsschicht - ja. Rufen Sie alle übereinstimmenden Benutzer-IDs von Ereignissen ab (erneut mit Aggregation, aber ohne Nachschlagen), und holen Sie dann Benutzer nach IDs. –

Antwort

1

Nach MongoDB Dokumentation

Die $ Lookup-Stufe hat eine Gleichheit Übereinstimmung zwischen einem Feld von den Eingabedokumenten mit einem Feld aus den Dokumenten der „verbunden“ Sammlung.

Für zB

„Alle Benutzer aus Frankreich, die mindestens haben 3 Nachrichten innerhalb der letzten 7 Tage gesendet“.

Um Daten für oben genannte Kriterien seiner Aggregatabfrage wird abrufen als

db.Event.aggregate(

    // Pipeline 
    [ 
     // Stage 1 
     { 
      $match: { 
      name:'message_sent', 
      timestamp:{$gte:ISODate("2016-10-25T04:39:52.667+0000"),$lte:ISODate("2016-11-01T04:39:52.667+0000")} 
      } 
     }, 

     // Stage 2 
     { 
      $group: { 
       _id:{user:'$user'}, 
       counter:{$sum:1} 
      } 
     }, 

     // Stage 3 
     { 
      $lookup: { 
       "from" : "User", 
       "localField" : "_id.user", 
       "foreignField" : "_id", 
       "as" : "user" 
      } 
     }, 

     // Stage 4 
     { 
      $match: { 
      'user.country':'France' , 
      counter:{$gte:3} 
      } 
     }, 

    ] 



); 
Verwandte Themen