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
}