Ewan Valentine
Ewan Valentine

Reputation: 3961

Multiple top level aggregate queries in a MongoDB Pipeline

I have the following query:

match := bson.D{{"$match", bson.D{{"venue", venueID}}}}
group := bson.D{{"$lookup", bson.M{
    "from":         "labels",
    "localField":   "label_ids",
    "foreignField": "_id",
    "as":           "labels",
}}, {"$graphLookup", bson.M{
    "from":             "menus",
    "startWith":        "$child_ids",
    "connectFromField": "child_ids",
    "connectToField":   "_id",
    "as":               "children",
    "maxDepth":         5,
    "depthField":       "level",
}}}

cur, err := m.collection.Aggregate(ctx, mongo.Pipeline{group, match})

I have two fields that are relational, one of them is a graph structure (menus), each parent element has an array of IDs for each child element.

The second field, labels, is just a one to many sort of query. Labels and menus are supposed to be re-usable, so not embedded in a single parent entity. The query outlined above makes sense to me, however I get the following error:

A pipeline stage specification object must contain exactly one field.

Thanks!

Upvotes: 1

Views: 199

Answers (1)

icza
icza

Reputation: 418505

Each element in a MongoDB pipeline must be a single stage, e.g. $match, $group etc.

Your group element contains 2 stages: $lookup and $graphLookup.

Split them and list them individually:

match := bson.D{{"$match", bson.D{{"venue", venueID}}}}
group := bson.D{{"$lookup", bson.M{
    "from":         "labels",
    "localField":   "label_ids",
    "foreignField": "_id",
    "as":           "labels",
}}}
graphLookup := bson.D{{"$graphLookup", bson.M{
    "from":             "menus",
    "startWith":        "$child_ids",
    "connectFromField": "child_ids",
    "connectToField":   "_id",
    "as":               "children",
    "maxDepth":         5,
    "depthField":       "level",
}}}

cur, err := m.collection.Aggregate(ctx, mongo.Pipeline{group, graphLookup, match})

Upvotes: 1

Related Questions