2017-07-28 3 views
0

Ich habe die folgende SQL (mysql) Abfrage, und ich möchte es in MongoDB konvertieren. Es wird immer im Grunde das Top-1-Dokument in jeder Gruppe:MongoDB - Abfrage - Top-Dokument pro Gruppe

SELECT A.* 
FROM ads AS A 
INNER JOIN (SELECT id 
      FROM ads 
      WHERE userId = 1 
      GROUP BY ad_code 
      HAVING MAX(ad_timestamp)) AS B ON B.id = A.id 

Von dem, was ich bisher gelesen gibt es mehr Möglichkeiten, um aggregierte Daten in MongoDB (mehr Infos unter MongoDB aggregation comparison: group(), $group and MapReduce):

  • Gruppe (funktioniert nicht auf sharded Sammlungen)
  • MapReduce
  • $ group

I Ich versuche das mit dem MongoDB Aggregation Framework zu lösen. Bisher habe ich dies:

db.ads.aggregate([ 
    { $match: { userId: ObjectId("5976e215769d8a4a4d75c514") } }, 
    { 
     $group: { 
      _id: "$ad_code", 
      latestTimestamp: { $max: "$ad_timestamp" }, 
     } 
    } 
]) 

Aber diese Rückkehr nicht die _ids der gefundenen Dokumenten, nur den Anzeigencode und max Zeitstempel, so kann ich die Daten nicht verwenden, um ganze Dokumente zu bekommen.

Diese Frage sehr relevant aussieht, aber es scheint nicht das gleiche Problem zu lösen, ich habe: Query one document per association from MongoDB

Dank

EDIT für doppelte Flagge: Diese Frage ist anders als andere, und Anders als bei der Frage, die ich verlinkt habe, verwendet die Lösung den Operanden $first, um eine 1-Übereinstimmung zu finden, und das Feld docIds, um nicht aggregierte Originaldokumente abzurufen. Dies ist anders als bei anderen Fragen, die sich Lösungen annäherten, teilweise als Ergebnis der Entwicklung von MongoDB im Laufe der Zeit.

Antwort

1

Es gibt nicht die _id zurück, weil Sie nicht danach gefragt haben. Diese Abfrage statt:

db.ads.aggregate([ 
    { $match: { userId: ObjectId("5976e215769d8a4a4d75c514") } }, 
    { $sort: {"ad_timestamp": -1}}, 
    { $group: { 
     _id: "$ad_code", 
     latestTimestamp: { $first: "$ad_timestamp" }, 
     docIds: {$first: "$_id"} 
     } 
    } 
]) 

Hier stellen wir zuerst sortiert nach ad_timestamp und die ersten jeder Gruppe mit $first bekommen, und gleiche gilt für die _id

+0

danke danke danke, das Zeug ist wirklich unheimlich am Anfang. – mils

+0

Und eine kurze Follow-up-Frage - bedeutet das, dass, wenn ich das Feld "lastTimestamp" nicht explizit verwende, ich es nicht deklarieren muss? Oder wird es für die erste Bedingung benötigt? Danke – mils

+1

@mils, wenn Sie nicht 'latestTimestamp' verwenden, können Sie es aus der Stufe **' $ group' ** entfernen, dies hat keine Auswirkungen auf die Ergebnisse – felix