2017-06-23 1 views
-1

Siehe Frage Match conditions and latest date from array, deren gute Lösung von Neil Lunn zur Verfügung gestellt wird.Komplex Mongo Abfrage

db.chat.find().pretty().limit(2) 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7662"), 
    "user1" : 1, 
    "user2" : 2, 
    "messages" : [ 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-05-01T00:00:00Z"), 
      "body" : "hiii 120" 
     }, 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-06-01T00:00:00Z"), 
      "body" : "hiii 121" 
     }, 
     { 
      "sender" : 2, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7663"), 
    "user1" : 1, 
    "user2" : 3, 
    "messages" : [ 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-05-02T00:00:00Z"), 
      "body" : "hiii 130" 
     }, 
     { 
      "sender" : 1, 
      "datetime" : ISODate("2017-06-02T00:00:00Z"), 
      "body" : "hiii 131" 
     }, 
     { 
      "sender" : 3, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 

Die Problemstellung hier ist ich brauche eine Liste der Benutzer, wo messages.sender = 1 Reihenfolge von datetime desc.

d.h Ausgang:

{ 
     "sender" : 1, 
     "receiver" : 2, 
     "datetime" : ISODate("2017-06-02T00:00:00Z"), 
     "body" : "hiii 131" 
    }, 
    { 
     "sender" : 1, 
     "receiver" : 2, 
     "datetime" : ISODate("2017-06-01T00:00:00Z"), 
     "body" : "hiii 121" 
    },      
    { 
     "sender" : 1, 
     "receiver" : 3, 
     "datetime" : ISODate("2017-05-02T00:00:00Z"), 
     "body" : "hiii 130" 
    }, 
    { 
     "sender" : 1, 
     "receiver" : 3, 
     "datetime" : ISODate("2017-05-01T00:00:00Z"), 
     "body" : "hiii 120" 
    }, 

Versuchte viele Abfrage aber nicht in der Lage die gewünschte Ausgabe zu erhalten.

Erklärung der Ausgabe:

db.chat.find().pretty().limit(2) 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7662"), 
    "user1" : 1, 
    "user2" : 2, 
    "messages" : [ 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-05-01T00:00:00Z"),**--- message will apear at No4 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 2. 
      "body" : "hiii 120" 
     }, 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-06-01T00:00:00Z"),**--- message will apear at No2 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 2. 
      "body" : "hiii 121" 
     }, 
     { 
      "sender" : 2, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("593921425ccc8150f35e7663"), 
    "user1" : 1, 
    "user2" : 3, 
    "messages" : [ 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-05-02T00:00:00Z"),** --- message will apear at No3 as sender=1. Also we need data of user1/user2 which is not equal to 1 i.e 3. 
      "body" : "hiii 130" 
     }, 
     { 
      "sender" : 1, 
      **"datetime" : ISODate("2017-06-02T00:00:00Z"),** --- message will apear at top as sender=1 and of max datetime. Also we need data of user1/user2 which is not equal to 1 i.e 3. 
      "body" : "hiii 131" 
     }, 
     { 
      "sender" : 3, 
      "datetime" : ISODate("2017-06-10T00:00:00Z"), 
      "body" : "hiii 2" 
     } 
    ] 
} 
+0

ich nicht bekommen. Ist das nur der Inhalt innerhalb der Arrays von etwas, das getan werden soll? Können Sie näher erläutern, wie die Daten ausgewählt werden sollen? –

+0

Ja Sein Inhalt innerhalb des Arrays + anderer Benutzer, der nicht der Absender ist ... Am wichtigsten ist es, basierend auf Datetime aller übereinstimmenden Zeilen von Nachrichten zu sortieren .... –

+0

Könnten Sie bitte ein bisschen beschreibender bitte sein? Sie haben im Grunde genommen zwei Sätze in die Frage geschrieben. Es braucht mehr Erklärung als das. Zum Beispiel gibt es Elemente in der Quelle, die nicht in der Ausgabe sind. Menschen lesen verdienen es zu verstehen, wie die Leistung erreicht wird. –

Antwort

1

mit den Daten getestet, geliefert. Dies funktioniert:

db.getCollection('test').aggregate([ 
{$unwind:"$messages"}, 
{$match : {"messages.sender" : 1}}, 
{$project:{ 
    "_id" : 0, 
    "sender" : "$messages.sender", 
    "datetime" : "$messages.datetime", 
    "body" : "$messages.body", 
    "receiver" : {$cond : {if: { $eq : ["$messages.sender","$user1"]}, then: "$user2", else: "$user1"}}, 
    } 
}, 
{$sort : {"datetime" : 1}} 
]) 

$unwind wird ein separates Objekt für alle Nachrichten erstellen.

$match hält nur diejenigen mit sender = 1

$project verwandelt sich die Daten in das Format, das Sie angefordert.

Da wir möchten, dass der Empfänger je nach Absender entweder Benutzer 1 oder Benutzer 2 ist, benötigen wir die $cond-Anweisung.

EDIT: $sort hinzufügen, weil ich über die Notwendigkeit lesen Sie Ihre Kommentare nur zum Sortieren von Datetime

+0

können wir dies tun, ohne die Verwendung von Abwickeln, da es eine teure Operation ist? –

+0

Es könnte mit viel mehr Arbeit möglich sein. Aber wenn Zeit ein Problem ist, ist die vorgeschlagene Ausgabe das Problem. Vielleicht ist dieses Problem auf der Anwendungsseite besser behoben als in der Datenbank? –