2017-01-25 3 views
0

Ich habe ein funktionierendes Beispiel einer SQL-Abfrage:SQL Unterabfrage Aggregation Analogie

SELECT a.user_id, a.latitude, a.longitude, a.accuracy, a.heading, a.speed, a.created_at 
FROM `location` a 
INNER JOIN (
    SELECT user_id, MAX(`created_at`) created_at 
    FROM location 
    WHERE created_at > :date 
    GROUP BY `user_id` 
) b ON a.`user_id` = b.`user_id` AND a.`created_at` = b.`created_at` 

, die für jeden Benutzer heutige letzte Position wählt

Wie kann ich diese Abfrage in MongoDB durchführen?

bekam ich den ersten Teil davon (subquery) in php:

$mongodb->getCollection('location')->aggregate([ 
    ['$match' => ['created_at' => ['$gte' => $beginOfDay]]], 
    [ 
     '$group' => [ 
      '_id' => '$user_id', 
      'lastTime' => ['$max' => '$created_at'] 
     ] 
    ] 
]); 

und would't neue Abfragen erstellen möchten ...

Vielleicht in MongoDB ist es leichter als in einer relationalen getan DB?

+1

Was ist das Sammlungsformat/die Form und die gewünschte Ausgabe? – felipsmartins

Antwort

0

Ich würde versuchen, es anders zu tun, anstatt die SQL-Abfrage zuzuordnen. Unten ist die Aggregation.

db.location.aggregate([ 
{$match : {$gte : beginOfDay}}, 
{$sort : {'user_id' : 1, 'created_at' : -1}}, 
{$group : { 
     _id : '$user_id', 
     created_at: { $first: "$created_at" }, 
     latitude: { $first: "$latitude" }, 
     longitude: { $first: "$longitude" }, 
     // ....similarly other fields 
     } 
} 
]); 

Was es im Grunde tut, ist Aggregat von allen Filtern des Dokuments, das auf den Tag erstellten Benutzer mit Daten hat dann durch User_id Sortieren und created_at absteigend und nach diesem Zeitpunkt in der Gruppe, für jede user_id es das erste Dokumentdaten erhält mit Hilfe von $first Betreiber.

Ich bin mir nicht sicher, wie man in PHP-Weise umwandeln oder wenn PHP-Treiber erlaubt $ zuerst oder nicht sicher, aber einen Versuch wert.

+0

Ja, es funktioniert! Endergebnis: '$ locations = $ mongodb-> getCollection ('location') -> aggregat ([[$ match '=> [' created_at '=> [' $ gte '=> $ beginOfDay]]], ['$ sort' => ['created_at' => -1]], [$ gruppe '=> [' _id '=>' $ user_id ',' latitude '=> [' $ first '=>' $ Breite '],' Länge '=> [' $ zuerst '=>' Länge '],' Genauigkeit '=> [' $ zuerst '=>' Genauigkeit '],' Überschrift '=> [' $ zuerst ' => '$ heading'], 'speed' => ['$ first' => '$ speed'], 'created_at' => ['$ first' => '$ created_at']]]]; ' –

+0

Andere Frage, wie kann ich' _id' die 'user_id' Taste bekommen? –

+0

Froh, dass es geholfen hat, würde ich sagen, fügen Sie ein weiteres Feld in der Gruppenphase etwas wie 'user_id' => ['$ first' => '$ user_id'], in diesem Fall erhalten Sie sowohl _id als auch user_id als Wert von user_id . Wenn Sie die ursprüngliche _id des Dokuments wollen, würde ich etwas wie 'o_id' => ['$ first' => '$ _id'] verwenden. Ich denke, das sollte funktionieren. –