2016-04-13 16 views
-1

Ich habe eine interessante Frage. Zum Beispiel habe ich eine Mongo-Sammlung mit start_date und end_date. Ich muss eine Aggregationsabfrage (oder mapReduce) erstellen, die ein Array von Arrays mit überlappenden Daten zurückgibt.Mongo Aggregation Abfrage

Zum Beispiel:

Sammlung:

[{ 
    _id: 1111111, 
    start_date: '10/04/2016', 
    end_data: '13/04/2016' 
}, 
{ 
    _id: 2222222, 
    start_date: '11/04/2016', 
    end_data: '20/04/2016' 
}, 
{ 
    _id: 3333333, 
    start_date: '10/05/2016', 
    end_data: '13/05/2016' 
}, 
{ 
    _id: 44444444, 
    start_date: '12/05/2016', 
    end_data: '15/05/2016' 
}, 
{ 
    _id: 55555555, 
    start_date: '18/04/2016', 
    end_data: '22/04/2016' 
}] 

zurückkehren sollte

[[1111111, 2222222], [3333333,44444444], [2222222, 55555555]] 
+0

Was ist, wenn Sie mehr als 2 Dokumente überlappend haben? – VonD

+1

Nein, das können Sie nicht mit Aggregation tun, Sie müssen es in der Anwendung tun. – BanksySan

+0

Unmöglich? nahhh ... Wie wäre es: Projekt (legte die 2 Daten in ein Array)> Abwickeln auf diesem Array> Gruppieren nach Datum> übereinstimmen, wenn ein Datum beginnt und das andere Ende ist> addToSet thesw gruppierte IDs ...... Es ist Die globale Idee, ich werde versuchen, den genauen Code zu geben. –

Antwort

0

Ich denke, so etwas tun würde, würde mit realen Daten versuchen müssen, zu validieren.

Ich poste es als eine allgemeine Idee, bitte jemand validieren und beheben Sie die Antwort, wenn Sie etwas klarer haben.

db.collection.aggregate([ 
{$project: { 
     _id:$_id, 
     dates: [{no:1, date:$start_date},{no:2,date:$end_date}] 
}}, 
{$unwind: $dates}, 
{$group: _id: $dates.date , 
     start_dates: {$addToSet: {$cond:{if:{$eq:[1, $dates.no]}, 
      then: [$_id], 
      else: null}}}, 
     end_dates: {$addToSet: {$cond:{if:{$eq:[2, $dates.no]}, 
      then: $_id, 
      else: null}}} 
}, 
{$match: {$start_dates.1:{$exists:true}, 
     $end_dates.1{$exists:true}}} 
]), //At this point you have objects like { aDate, [lst of ids with that date as start], [lst of ids with that date as end]} 
{$unwind: $start_dates}, 
{$group: {_id: {date:$_id, id:$start_dates.1}, // You still have 1 array of array per dates, you can always put "_id: 1" to have only 1 array as answer 
     res: {$addToSet:{$start_dates: {$each: $end_dates}}}} 
} 
Verwandte Themen