Skip to content

Instantly share code, notes, and snippets.

@KScaesar
Created March 4, 2022 09:55
Show Gist options
  • Select an option

  • Save KScaesar/c13427787f8d4aa4ef8750476f04e42c to your computer and use it in GitHub Desktop.

Select an option

Save KScaesar/c13427787f8d4aa4ef8750476f04e42c to your computer and use it in GitHub Desktop.

mongo shell

db.variousInstance.aggregate([
    {
        $match: {}
    },
    {
        $sort: {createAt: -1},
    },
    {
        $skip: 0,
    },
    {
        $limit: 10,
    },
    {
        $lookup: {
            from: "gcpInstanceInventory",
            localField: "_id",
            foreignField: "_id",
            as: "gcp_vm",
        },
    },
    {
        $lookup: {
            from: "awsInstanceInventory",
            localField: "_id",
            foreignField: "_id",
            as: "aws_vm",
        },
    },
    {
        $lookup: {
            from: "gcpSubnetInventory",
            localField: "subnetId",
            foreignField: "_id",
            as: "gcp_subnet",
        },
    },
    {
        $lookup: {
            from: "awsSubnetInventory",
            localField: "subnetId",
            foreignField: "_id",
            as: "aws_subnet",
        },
    },
    {
        $project: {
            _id: 1,
            envId: 1,
            orgId: 1,
            providerType: 1,
            subnetId: 1,
            location: 1,
            regionCloudId: 1,
            createAt: 1,
            subnetName:
                {
                    $switch: {
                        branches: [
                            {case: {$eq: ["$providerType", "gcp"]}, then: "$gcp_subnet.name"},
                            {case: {$eq: ["$providerType", "aws"]}, then: "$aws_subnet.name"}
                        ],
                    }
                },
            resourceState:
                {
                    $switch: {
                        branches: [
                            {case: {$eq: ["$providerType", "gcp"]}, then: "$gcp_vm.resourceState"},
                            {case: {$eq: ["$providerType", "aws"]}, then: "$aws_vm.resourceState"}
                        ],
                    }
                },
            operation:
                {
                    $switch: {
                        branches: [
                            {case: {$eq: ["$providerType", "gcp"]}, then: "$gcp_vm.operation"},
                            {case: {$eq: ["$providerType", "aws"]}, then: "$aws_vm.operation"}
                        ],
                    }
                },
        }
    },
    {$unwind: "$subnetName"},
    {$unwind: "$resourceState"},
    {$unwind: "$operation"},
])

golang mongo-driver

func NewVariousInstanceRepo(client *mongo.Client) *VariousInstanceRepo {

	return &VariousInstanceRepo{
		collection: client.Database(cloudDatabaseName).Collection("variousInstance"),

		sortStage: bson.D{{"$sort", bson.M{"createAt": -1}}},

		lookupStage: []bson.D{
			{{
				"$lookup", bson.D{
					{"from", "gcpInstanceInventory"},
					{"localField", "_id"},
					{"foreignField", "_id"},
					{"as", "gcp_vm"},
				},
			}},
			{{
				"$lookup", bson.D{
					{"from", "awsInstanceInventory"},
					{"localField", "_id"},
					{"foreignField", "_id"},
					{"as", "aws_vm"},
				},
			}},

			{{
				"$lookup", bson.D{
					{"from", "gcpSubnetInventory"},
					{"localField", "subnetId"},
					{"foreignField", "_id"},
					{"as", "gcp_subnet"},
				},
			}},
			{{
				"$lookup", bson.D{
					{"from", "awsSubnetInventory"},
					{"localField", "subnetId"},
					{"foreignField", "_id"},
					{"as", "aws_subnet"},
				},
			}},
		},

		projectStage: bson.D{
			{
				"$project", bson.M{
					"_id":           1,
					"envId":         1,
					"orgId":         1,
					"providerType":  1,
					"subnetId":      1,
					"location":      1,
					"regionCloudId": 1,
					"createAt":      1,

					"subnetName": bson.M{
						"$switch": bson.M{
							"branches": bson.A{
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderGcp}},
									"then": "$gcp_subnet.name",
								},
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderAws}},
									"then": "$aws_subnet.name",
								},
							},
						},
					},
					"resourceState": bson.M{
						"$switch": bson.M{
							"branches": bson.A{
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderGcp}},
									"then": "$gcp_vm.resourceState",
								},
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderAws}},
									"then": "$aws_vm.resourceState",
								},
							},
						},
					},
					"operation": bson.M{
						"$switch": bson.M{
							"branches": bson.A{
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderGcp}},
									"then": "$gcp_vm.operation",
								},
								bson.M{
									"case": bson.M{"$eq": bson.A{"$providerType", domain.ProviderAws}},
									"then": "$aws_vm.operation",
								},
							},
						},
					},
				},
			},
		},

		unwindStage: []bson.D{
			{{"$unwind", "$subnetName"}},
			{{"$unwind", "$resourceState"}},
			{{"$unwind", "$operation"}},
		},
	}
}

type VariousInstanceRepo struct {
	collection   *mongo.Collection
	sortStage    bson.D
	lookupStage  []bson.D
	projectStage bson.D
	unwindStage  []bson.D
}

func (repo VariousInstanceRepo) GetVariousInstanceList(ctx context.Context, req domain.VariousInstanceViewQueryRequest) (resp domain.VariousInstanceViewResponse, err error) {
	filter := database.MongoFilter(req.VariousInstanceViewFilter)
	pageOption := req.PageOption.Init()

	pipeline := mongo.Pipeline{
		{{"$match", filter}},
		repo.sortStage,
		{{"$skip", pageOption.OffsetOrSkip()}},
		{{"$limit", pageOption.PageSize}},
	}
	pipeline = append(pipeline, repo.lookupStage...)
	pipeline = append(pipeline, repo.projectStage)
	pipeline = append(pipeline, repo.unwindStage...)

	cursor, err := repo.collection.Aggregate(ctx, pipeline)
	if err != nil {
		err = database.TranslateMongoError(err)
		return
	}

	views := make([]domain.VariousInstanceView, 0, pageOption.PageSize)
	err = cursor.All(ctx, &views)
	if err != nil {
		err = database.TranslateMongoError(err)
		return
	}

	total, err := repo.collection.CountDocuments(ctx, filter)
	if err != nil {
		err = database.TranslateMongoError(err)
		return
	}

	pageResponse := pkg.NewPageResponse(pageOption, total)
	resp = domain.NewVariousInstanceViewResponse(pageResponse, views)
	return resp, nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment