How can I decode lookup result to nested structure?

XMLWordPrintableJSON

    • 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 []}
      

            Assignee:
            Kristofer Brandow (Inactive)
            Reporter:
            성욱 조
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: