Skip to content

Commit edae703

Browse files
authored
Add events aggregation on upload (#64)
* Add events aggregation on upload * comments
1 parent 098ed8e commit edae703

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

uploader/uploader.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func Upload(inDir string, replace bool) {
5959
}
6060
}
6161

62+
buildEvents(client, ctx)
6263
}
6364

6465
// Generic upload function to upload parsed JSON data to the Mongo database
@@ -167,3 +168,158 @@ func UploadData[T any](client *mongo.Client, ctx context.Context, fptr *os.File,
167168

168169
defer fptr.Close()
169170
}
171+
172+
// MongoDB aggregation run only when sections changes, instead of as a view where it's run for each query
173+
func buildEvents(client *mongo.Client, ctx context.Context) {
174+
sections := getCollection(client, "sections")
175+
176+
pipeline := mongo.Pipeline{
177+
//separate each meeting
178+
{{Key: "$unwind", Value: "$meetings"}},
179+
//remove bad data
180+
{{Key: "$match", Value: bson.D{
181+
{Key: "meetings.location.building", Value: bson.D{{Key: "$ne", Value: "No"}}},
182+
}}},
183+
//remove time from meeting start date
184+
{{Key: "$addFields", Value: bson.D{
185+
{Key: "meetings.start_date", Value: bson.D{
186+
{Key: "$dateTrunc", Value: bson.D{
187+
{Key: "date", Value: "$meetings.start_date"},
188+
{Key: "unit", Value: "day"},
189+
}},
190+
}},
191+
}}},
192+
//add a field thats a list of all days the class occurs
193+
//by generating all days in semester and removing those that don't match MW for example
194+
{{Key: "$addFields", Value: bson.D{
195+
{Key: "meeting_dates", Value: bson.D{
196+
{Key: "$filter", Value: bson.D{
197+
{Key: "input", Value: bson.D{
198+
{Key: "$map", Value: bson.D{
199+
{Key: "input", Value: bson.D{
200+
{Key: "$range", Value: bson.A{
201+
0,
202+
bson.D{{Key: "$dateDiff", Value: bson.D{
203+
{Key: "startDate", Value: bson.D{{Key: "$toDate", Value: "$meetings.start_date"}}},
204+
{Key: "endDate", Value: bson.D{{Key: "$toDate", Value: "$meetings.end_date"}}},
205+
{Key: "unit", Value: "day"},
206+
}}},
207+
1,
208+
}},
209+
}},
210+
{Key: "as", Value: "offset"},
211+
{Key: "in", Value: bson.D{
212+
{Key: "$dateAdd", Value: bson.D{
213+
{Key: "startDate", Value: bson.D{{Key: "$toDate", Value: "$meetings.start_date"}}},
214+
{Key: "unit", Value: "day"},
215+
{Key: "amount", Value: "$$offset"},
216+
}},
217+
}},
218+
}},
219+
}},
220+
{Key: "as", Value: "date"},
221+
{Key: "cond", Value: bson.D{
222+
{Key: "$in", Value: bson.A{
223+
bson.D{{Key: "$dayOfWeek", Value: "$$date"}},
224+
bson.D{{Key: "$map", Value: bson.D{
225+
{Key: "input", Value: "$meetings.meeting_days"},
226+
{Key: "as", Value: "day"},
227+
{Key: "in", Value: bson.D{
228+
{Key: "$switch", Value: bson.D{
229+
{Key: "branches", Value: bson.A{
230+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Sunday"}}}}, {Key: "then", Value: 1}},
231+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Monday"}}}}, {Key: "then", Value: 2}},
232+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Tuesday"}}}}, {Key: "then", Value: 3}},
233+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Wednesday"}}}}, {Key: "then", Value: 4}},
234+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Thursday"}}}}, {Key: "then", Value: 5}},
235+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Friday"}}}}, {Key: "then", Value: 6}},
236+
bson.D{{Key: "case", Value: bson.D{{Key: "$eq", Value: bson.A{"$$day", "Saturday"}}}}, {Key: "then", Value: 7}},
237+
}},
238+
{Key: "default", Value: nil},
239+
}},
240+
}},
241+
}}},
242+
}},
243+
}},
244+
}},
245+
}},
246+
}}},
247+
//separate for each meeting data
248+
{{Key: "$unwind", Value: "$meeting_dates"}},
249+
//remove data before today
250+
{{Key: "$match", Value: bson.D{
251+
{Key: "$expr", Value: bson.D{
252+
{Key: "$gte", Value: bson.A{
253+
"$meeting_dates",
254+
bson.D{{Key: "$dateSubtract", Value: bson.D{
255+
{Key: "startDate", Value: bson.D{{Key: "$dateTrunc", Value: bson.D{
256+
{Key: "date", Value: "$$NOW"},
257+
{Key: "unit", Value: "day"},
258+
}}}},
259+
{Key: "unit", Value: "day"},
260+
{Key: "amount", Value: 7},
261+
}}},
262+
}},
263+
}},
264+
}}},
265+
//group into building > room hierarchy format
266+
{{Key: "$group", Value: bson.D{
267+
{Key: "_id", Value: bson.D{
268+
{Key: "date", Value: "$meeting_dates"},
269+
{Key: "building", Value: "$meetings.location.building"},
270+
{Key: "room", Value: "$meetings.location.room"},
271+
}},
272+
{Key: "events", Value: bson.D{
273+
{Key: "$push", Value: bson.D{
274+
{Key: "section", Value: "$_id"},
275+
{Key: "start_time", Value: "$meetings.start_time"},
276+
{Key: "end_time", Value: "$meetings.end_time"},
277+
}},
278+
}},
279+
}}},
280+
{{Key: "$group", Value: bson.D{
281+
{Key: "_id", Value: bson.D{
282+
{Key: "date", Value: "$_id.date"},
283+
{Key: "building", Value: "$_id.building"},
284+
}},
285+
{Key: "rooms", Value: bson.D{
286+
{Key: "$push", Value: bson.D{
287+
{Key: "room", Value: "$_id.room"},
288+
{Key: "events", Value: "$events"},
289+
}},
290+
}},
291+
}}},
292+
{{Key: "$group", Value: bson.D{
293+
{Key: "_id", Value: bson.D{
294+
{Key: "date", Value: "$_id.date"},
295+
}},
296+
{Key: "buildings", Value: bson.D{
297+
{Key: "$push", Value: bson.D{
298+
{Key: "building", Value: "$_id.building"},
299+
{Key: "rooms", Value: "$rooms"},
300+
}},
301+
}},
302+
}}},
303+
//format date
304+
{{Key: "$project", Value: bson.D{
305+
{Key: "_id", Value: 0},
306+
{Key: "date", Value: bson.D{
307+
{Key: "$dateToString", Value: bson.D{
308+
{Key: "format", Value: "%Y-%m-%d"},
309+
{Key: "date", Value: "$_id.date"},
310+
}},
311+
}},
312+
{Key: "buildings", Value: 1},
313+
}}},
314+
//set as events collection
315+
{{Key: "$out", Value: "events"}},
316+
}
317+
318+
cursor, err := sections.Aggregate(ctx, pipeline)
319+
if err != nil {
320+
log.Panic(err)
321+
}
322+
defer cursor.Close(ctx)
323+
324+
log.Println("Done aggregating events!")
325+
}

0 commit comments

Comments
 (0)