英文:
need to project nested array using mgo
问题
我正在使用Go语言作为我的应用程序后端,MongoDB作为数据库。我遇到了一个问题,我需要比较姓名并投影请假数组,同时我还需要投影该请假的证书。由于我只需要从员工结构中获取少量信息,所以我想使用管道和投影来实现。
以下是我的代码:
type (
Employee struct {
Name string
Password string
EmailAddress string
Position string
Gender string
Nationality string
Department string
MaritalStatus string
Approvedby string
JoinDate time.Time
ConfirmationDate time.Time
EndDate time.Time
Leave []*LeaveInfo
}
LeaveInfo struct {
Total float64
Id int
Days float64
From time.Time
To time.Time
Status string
Certificate []*CertificateInfo
}
CertificateInfo struct {
FileName string
FileType string
FileSize int
}
)
数据库结构如下:
{
"_id" : ObjectId("58213e14927a62f3cf04e05b"),
"name" : "string",
"password" : "string",
"emailaddress" : "string",
"position" : "string",
"gender" : "string",
"maritalstatus" : "string",
"approvedby" : "string",
"nationality" : "german",
"department" : "account",
"joindate" : ISODate("2016-09-19T00:00:00.000Z"),
"confirmationdate" : Date(-62135596800000),
"enddate" : Date(-62135596800000),
"Leave" : [
{
"total" : 20.0,
"id" : 0,
"days" : 0.0,
"type" : "",
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"status" : "",
"certificate" : [
{
"filename" : "malaysia",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "singapore",
"filetype" : ".zip",
"filesize" : 1234
}
]
},
{
"total" : 19.0,
"id" : 1,
"days" : 1.0,
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"applieddate" : ISODate("2016-11-08T02:53:38.902Z"),
"status" : "Processing",
"approveddate" : Date(-62135596800000),
"certificate" : [
{
"filename" : "germany",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "england",
"filetype" : ".zip",
"filesize" : 1234
}
]
},
{
"total" : 18.0,
"id" : 2,
"days" : 1.0,
"mdays" : 0.0,
"type" : "annualleave",
"daytype" : "FullDay",
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"applieddate" : ISODate("2016-11-08T05:36:21.579Z"),
"status" : "Processing",
"approveddate" : Date(-62135596800000),
"certificate" : [
{
"filename" : "india",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "france",
"filetype" : ".zip",
"filesize" : 1234
}
]
}
]
}
你的Go代码如下:
pipe3 := c.Pipe([]bson.M{
{
"$match": bson.M{
"name": name,
},
},
{
"$unwind": "$leave",
},
{
"$project": bson.M{
"_id": false,
"name": 1,
"Id": "$leave.id",
"Total": "$leave.total",
"Days": "$leave.days",
"Status": "$leave.status",
},
},
})
问题是我不知道如何检索与特定请假相关的所有证书的所有信息。请注意,证书是一个至少有两个索引的数组。
我需要类似于以下输出:
{
"name": "John",
"Id": "1",
"Total": "10.0",
"Days": "2.0",
"Status": "Process",
"Certificate": [
{
"filename": "certificate1",
"filesize": "size1"
},
{
"filename": "certificate2",
"filesize": "size2"
}
]
}
{
"name": "John",
"Id": "2",
"Total": "8.0",
"Days": "2.0",
"Status": "Process",
"Certificate": [
{
"filename": "certificate1",
"filesize": "size1"
},
{
"filename": "certificate2",
"filesize": "size2"
}
]
}
是否可以使用$project
实现这一点,或者是否有其他方法可以实现?感谢任何帮助。谢谢!
英文:
I m using go lang as the back end of my application and mongoDB as the database.I am facing a problem where i compare the name and project the leave array and inside that i also need to project the certificates for that leave.Since i need only little info from the employee struct i wanted to implement using pipe and project.
type (
Employee struct {
Name string
Password string
EmailAddress string
Position string
Gender string
Nationality string
Department string
MaritalStatus string
Approvedby string
JoinDate time.Time
ConfirmationDate time.Time
EndDate time.Time
Leave []*LeaveInfo
}
LeaveInfo struct {
Total float64
Id int
Days float64
From time.Time
To time.Time
Status string
Certificate []*CertificateInfo
}
CertificateInfo struct {
FileName string
FileType string
FileSize int
}
The database structure is as follows
{
"_id" : ObjectId("58213e14927a62f3cf04e05b"),
"name" : "string",
"password" : "string",
"emailaddress" : "string",
"position" : "string",
"gender" : "string",
"maritalstatus" : "string",
"approvedby" : "string",
"nationality" : "german",
"department" : "account",
"joindate" : ISODate("2016-09-19T00:00:00.000Z"),
"confirmationdate" : Date(-62135596800000),
"enddate" : Date(-62135596800000),
"Leave" : [
{
"total" : 20.0,
"id" : 0,
"days" : 0.0,
"type" : "",
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"status" : "",
"certificate" : [
{
"filename" : "malaysia",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "singapore",
"filetype" : ".zip",
"filesize" : 1234
}
]
},
{
"total" : 19.0,
"id" : 1,
"days" : 1.0,
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"applieddate" : ISODate("2016-11-08T02:53:38.902Z"),
"status" : "Processing",
"approveddate" : Date(-62135596800000),
"certificate" : [
{
"filename" : "germany",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "england",
"filetype" : ".zip",
"filesize" : 1234
}
]
},
{
"total" : 18.0,
"id" : 2,
"days" : 1.0,
"mdays" : 0.0,
"type" : "annualleave",
"daytype" : "FullDay",
"from" : ISODate("2016-12-12T00:00:00.000Z"),
"to" : ISODate("2016-12-12T00:00:00.000Z"),
"applieddate" : ISODate("2016-11-08T05:36:21.579Z"),
"status" : "Processing",
"approveddate" : Date(-62135596800000),
"certificate" : [
{
"filename" : "india",
"filetype" : ".zip",
"filesize" : 1234
},
{
"filename" : "france",
"filetype" : ".zip",
"filesize" : 1234
}
]
}
]
}
My code in golang is as follows
pipe3 := c.Pipe([]bson.M{
{
"$match": bson.M{
"name":name
},
},
{
"$unwind": "$leave",
},
{
"$project": bson.M{
"_id": false,
"name": 1,
"Id": "$leave.id",
"Total": "$leave.total",
"Days": "$leave.days",
"Status": "$leave.status",
},
},
})
The problem here is i dont know how to retrieve all the info of the certificates related to that particular leave.Please note that the certificate is an array with atleast two index in it...
I need an output similar to this.
"name": "John",
"Id": "1",
"Total": "10.0",
"Days": "2.0",
"Status": "Process",
"Certificate" : [
{
"filename":"certificate1",
"filesize":"size1"
},
{
"filename":"certificate2",
"filesize":"size2"
}
]
"name": "John",
"Id": "2",
"Total": "8.0",
"Days": "2.0",
"Status": "Process",
"Certificate" : [
{
"filename":"certificate1",
"filesize":"size1"
},
{
"filename":"certificate2",
"filesize":"size2"
}
]
Is this possible using project.or is there any other way to do this.Appreciate any help.Please.Thanks
答案1
得分: 1
根据您提供的文档结构示例,您只需通过$project
将certificate
暴露在$project
中,如下所示:
pipeline := []bson.M{
{"$match": bson.M{"name": "string"}},
{"$unwind": "$Leave"},
{"$project": bson.M{
"_id": false,
"name": 1,
"Id": "$Leave.id",
"Total": "$Leave.total",
"Days": "$Leave.days",
"Status": "$Leave.status",
"Certificate": "$Leave.certificate"},
},
}
pipe := collection.Pipe(pipeline)
response := []bson.M{}
err = pipe.All(&response)
由于您已经在Leave
上使用了$unwind
,每个请假请求都有单独的文档。上述聚合的输出将如下所示:
{
"name": "string",
"Id": 0,
"Total": 20,
"Days": 0,
"Status": "",
"Certificate": [
{
"filename": "malaysia",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "singapore",
"filetype": ".zip",
"filesize": 1234
}
]
},
{
"name": "string",
"Id": 1,
"Total": 19,
"Days": 1,
"Status": "Processing",
"Certificate": [
{
"filename": "germany",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "england",
"filetype": ".zip",
"filesize": 1234
}
]
},
{
"name": "string",
"Id": 2,
"Total": 18,
"Days": 1,
"Status": "Processing",
"Certificate": [
{
"filename": "india",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "france",
"filetype": ".zip",
"filesize": 1234
}
]
}
每个请假请求都有与之关联的相应证书。
英文:
Using on your document structure example above, you just have to expose certificate
through $project
as below:
pipeline := []bson.M{
{"$match": bson.M{"name":"string"}},
{"$unwind": "$Leave"},
{"$project": bson.M{
"_id": false,
"name": 1,
"Id": "$Leave.id",
"Total": "$Leave.total",
"Days": "$Leave.days",
"Status": "$Leave.status",
"Certificate": "$Leave.certificate"},
},
}
pipe := collection.Pipe(pipeline)
response := []bson.M{}
err = pipe.All(&response)
As you already use $unwind
on Leave
, you have individual documents per leave request. The output of the above aggregation would be:
{
"name": "string",
"Id": 0,
"Total": 20,
"Days": 0,
"Status": "",
"Certificate": [
{
"filename": "malaysia",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "singapore",
"filetype": ".zip",
"filesize": 1234
}
]
},
{
"name": "string",
"Id": 1,
"Total": 19,
"Days": 1,
"Status": "Processing",
"Certificate": [
{
"filename": "germany",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "england",
"filetype": ".zip",
"filesize": 1234
}
]
},
{
"name": "string",
"Id": 2,
"Total": 18,
"Days": 1,
"Status": "Processing",
"Certificate": [
{
"filename": "india",
"filetype": ".zip",
"filesize": 1234
},
{
"filename": "france",
"filetype": ".zip",
"filesize": 1234
}
]
}
Where each leave request, has their own corresponding certificates associated with the leave.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论