-
Type:
Task
-
Resolution: Works as Designed
-
Priority:
Major - P3
-
None
-
Affects Version/s: 0.1.0
-
Component/s: BSON
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
How can I decode lookup(aggregation) result to nested structure?
This is my test code and I expected all inner structures are decoded.
package main import ( "context" "fmt" "github.com/mongodb/mongo-go-driver/bson" "github.com/mongodb/mongo-go-driver/mongo" "github.com/mongodb/mongo-go-driver/bson/primitive" "github.com/mongodb/mongo-go-driver/mongo/options" ) func main() { type item struct { ID primitive.ObjectID `bson:"_id"` Name string Price int } type order struct { ID primitive.ObjectID `bson:"_id"` Name string Item []primitive.ObjectID Qty int } type user struct{ ID primitive.ObjectID `bson:"_id"` Name string Orders []primitive.ObjectID } type fOrder struct { ID primitive.ObjectID `bson:"_id"` Name string Item []item Qty int } type fUser struct { ID primitive.ObjectID `bson:"_id"` Name string Orders []fOrder } ctx := context.Background() client, err := mongo.NewClient("mongodb://localhost:27027") if err != nil { panic(err) } err = client.Connect(ctx) if err != nil { panic(err) } db := client.Database("testDb") err = db.Drop(ctx) if err != nil { panic(err) } items := client.Database("testDb").Collection("items") orders := client.Database("testDb").Collection("orders") users := client.Database("testDb").Collection("users") item1 := item{ID:primitive.NewObjectID(), Name: "a", Price: 12} item2 := item{ID:primitive.NewObjectID(), Name: "b", Price: 20} item3 := item{ID:primitive.NewObjectID(), Name: "c", Price: 5} item4 := item{ID:primitive.NewObjectID(), Name: "d", Price: 4} item5 := item{ID:primitive.NewObjectID(), Name: "e", Price: 50} order1 := order{ID: primitive.NewObjectID(), Name: "o1", Item: []primitive.ObjectID{item1.ID, item2.ID}, Qty: 1} order2 := order{ID: primitive.NewObjectID(), Name: "o2", Item: []primitive.ObjectID{item2.ID, item3.ID, item4.ID}, Qty: 3} order3 := order{ID: primitive.NewObjectID(), Name: "o3", Item: []primitive.ObjectID{item5.ID, item3.ID}, Qty: 2} order4 := order{ID: primitive.NewObjectID(), Name: "o4", Item: []primitive.ObjectID{item5.ID}, Qty: 1} order5 := order{ID: primitive.NewObjectID(), Name: "o5", Item: []primitive.ObjectID{item1.ID, item2.ID, item3.ID, item4.ID}, Qty: 5} user1 := user{ID:primitive.NewObjectID(), Name: "John", Orders:[]primitive.ObjectID{order1.ID, order2.ID}} user2 := user{ID:primitive.NewObjectID(), Name: "Brown", Orders:[]primitive.ObjectID{order3.ID, order4.ID, order5.ID}} err = client.UseSession(ctx, func(sessionContext mongo.SessionContext) error { if err != nil { return err } _, err = items.InsertMany(sessionContext, []interface{}{item1, item2, item3, item4, item5}) if err != nil { return err } _, err = orders.InsertMany(sessionContext, []interface{}{order1, order2, order3, order4, order5}) if err != nil { return err } _, err = users.DeleteOne(sessionContext, bson.D{{"_id", "a"}}) if err != nil { return err } _, err = users.InsertMany(sessionContext, []interface{}{user1, user2}) if err != nil { return err } return nil }) if err != nil { panic(err) } cur, err := users.Aggregate(nil, mongo.Pipeline{ {{"$lookup", bson.D{{"from", "orders"}, {"localField","orders"}, {"foreignField", "_id"}, {"as", "orders"}}}}, {{"$unwind", "$orders"}}, {{"$lookup", bson.D{{"from", "items"}, {"localField","orders.item"}, {"foreignField", "_id"}, {"as", "item"}}}}, {{"$group", bson.D{{"_id", "$_id"}, {"name", bson.D{{"$first","$name"}}}, {"orders", bson.D{{"$push", "$orders"}}}}}, }}, options.Aggregate()) if err != nil{ panic(err) } for cur.Next(nil) { u := new(fUser) cur.Decode(u) fmt.Println(u) } }
But the result is:
&{ObjectID("5c0f4181ae3cac264bc9e1ec") Brown []} &{ObjectID("5c0f4181ae3cac264bc9e1eb") John []}