2016-04-21 3 views
1

Ich versuche, eine Abfrage mit folgendem Dokument in Mongo db zu bilden:MongoDB: auf demselben Dokument resultiert aus Abfrage in derselben Abfrage mit

myMetaDataDoc document 
{ 
    _id: <objectId>, 
    tour: 
    { 
    tourId: "TOURID1", 
    stops: [{ 
     locationId: "LOC1", 
     stopId: "STOPID1", 
     ... 
    ],[ 
     locationId: "LOC2", 
     stopId: "STOPID2", 
    ]} 
    } 
    schedule:{ 
    stopSchedules: [{ 
     stopId: "STOPID1" 
     ... 
    },{ 
     stopId: "STOPID2" 
     ... 
    }] 
    } 
} 

Grundsätzlich mag ich in alle Register mit ihren jeweiligen Planinformationen erhalten ein Ort. Ich benötige eine einzelne Abfrage folgendes zu erreichen:

  1. Abfrage alle mit dem Standort stoppt (zB LOC1.)
  2. Abfrage alle stopSchedules mit stops.stopId von 1.
  3. Rückkehr stoppt + Pläne

Was ich versuchte, war Aggregat zu verwenden, konnte aber nicht die stops.stopId in derselben Abfrage verwendet werden. Dies war mein Versuch:

db.myMetaDataDoc.aggregate([ 
{$match : {'tour.stops.locationId':'LOC1'}}, // all tour stops with locationId as LOC1 
{$unwind : '$tour.stops'}, // break all stops 
{$match : {'tour.stops.locationId':'LOC1'} }, // all tour with only stops with locationId as LOC1 
{$unwind : '$schedule.stopSchedules'}, // break all stopschedules 
{$match : {'schedule.stopSchedules.stopsId' : {$in :<stopId array>}} } // missing array of stopId 
]) 

letzten $ Spiel entfernen, erhalte ich alle Zeilen mit Single "tour.stops" und Single "schedules.stopSchedules".

{ "_id" : ObjectId("xx1"), "myMetaDataDoc" : {"tour" : { "tourId" : "TOURID1", "stops" : { "locationId" : "LOC1", "stopId" : "STOPID1"} } , "schedule" : { "stopSchedules" : { "stopId" : "STOPID1", ...}}}} 
{ "_id" : ObjectId("xx2"), "myMetaDataDoc" : {"tour" : { "tourId" : "TOURID1", "stops" : { "locationId" : "LOC1", "stopId" : "STOPID1"} } , "schedule" : { "stopSchedules" : { "stopId" : "STOPID2", ...}}}} 

Aus diesem Satz von Zeilen Ich brauche nur solche, bei denen stops.stopId schedules.stopSchedules.stopId entspricht. Es scheint, Aggregat mag $ wo nicht. Sollte ich stattdessen mapreduce() verwenden? oder ein serverseitiges Skript?

Schätzen Sie alle Vorschläge.

Antwort

0

Nachdem ich ein bisschen mit aggregat und $ eq operator ausprobiert habe, glaube ich, dass ich etwas bekommen habe, was ich brauchte. Was ich getan habe, war, die letzte Übereinstimmung zu überspringen und die Gruppe in allen Zeilen mit einem gültigen Feld zu verwenden, indem $ eq operator verwendet wird. Ich entferne es später mit Projektion.

db.myMetaDataDoc.aggregate([ 
{$match : {'tour.stops.locationId':'LOC1'}}, // all tour stops with locationId as LOC1 
{$unwind : '$tour.stops'}, // break all stops 
{$match : {'tour.stops.locationId':'LOC1'} }, // all tour with only stops with locationId as LOC1 
{$unwind : '$schedule.stopSchedules'}, // break all stopschedules 
{$group : { 
    '_id': '$tour.tourId', 
    valid: {$first: {$cond: [{$eq: ['$tour.stops.stopId','$schedule.stopSchedules.stopId']}, '1', '0']}}, // validate row 
    stop : { $first: '$tour.stops'}, 
    schedule : {$first: '$schedule.stopSchedules'} 
{$match : {'valid':'1'} }, // skip invalid rows 
{ 
    $project: {   // remove valid field 
     _id: 1, 
     stop: 1, 
     schedule:1 
    } 
} 
]) 

Ich bin immer noch offen für eine bessere Lösung.