需要使用mgo来投影嵌套数组。

huangapple go评论116阅读模式
英文:

need to project nested array using mgo

问题

我正在使用Go语言作为我的应用程序后端,MongoDB作为数据库。我遇到了一个问题,我需要比较姓名并投影请假数组,同时我还需要投影该请假的证书。由于我只需要从员工结构中获取少量信息,所以我想使用管道和投影来实现。

以下是我的代码:

  1. type (
  2. Employee struct {
  3. Name string
  4. Password string
  5. EmailAddress string
  6. Position string
  7. Gender string
  8. Nationality string
  9. Department string
  10. MaritalStatus string
  11. Approvedby string
  12. JoinDate time.Time
  13. ConfirmationDate time.Time
  14. EndDate time.Time
  15. Leave []*LeaveInfo
  16. }
  17. LeaveInfo struct {
  18. Total float64
  19. Id int
  20. Days float64
  21. From time.Time
  22. To time.Time
  23. Status string
  24. Certificate []*CertificateInfo
  25. }
  26. CertificateInfo struct {
  27. FileName string
  28. FileType string
  29. FileSize int
  30. }
  31. )

数据库结构如下:

  1. {
  2. "_id" : ObjectId("58213e14927a62f3cf04e05b"),
  3. "name" : "string",
  4. "password" : "string",
  5. "emailaddress" : "string",
  6. "position" : "string",
  7. "gender" : "string",
  8. "maritalstatus" : "string",
  9. "approvedby" : "string",
  10. "nationality" : "german",
  11. "department" : "account",
  12. "joindate" : ISODate("2016-09-19T00:00:00.000Z"),
  13. "confirmationdate" : Date(-62135596800000),
  14. "enddate" : Date(-62135596800000),
  15. "Leave" : [
  16. {
  17. "total" : 20.0,
  18. "id" : 0,
  19. "days" : 0.0,
  20. "type" : "",
  21. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  22. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  23. "status" : "",
  24. "certificate" : [
  25. {
  26. "filename" : "malaysia",
  27. "filetype" : ".zip",
  28. "filesize" : 1234
  29. },
  30. {
  31. "filename" : "singapore",
  32. "filetype" : ".zip",
  33. "filesize" : 1234
  34. }
  35. ]
  36. },
  37. {
  38. "total" : 19.0,
  39. "id" : 1,
  40. "days" : 1.0,
  41. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  42. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  43. "applieddate" : ISODate("2016-11-08T02:53:38.902Z"),
  44. "status" : "Processing",
  45. "approveddate" : Date(-62135596800000),
  46. "certificate" : [
  47. {
  48. "filename" : "germany",
  49. "filetype" : ".zip",
  50. "filesize" : 1234
  51. },
  52. {
  53. "filename" : "england",
  54. "filetype" : ".zip",
  55. "filesize" : 1234
  56. }
  57. ]
  58. },
  59. {
  60. "total" : 18.0,
  61. "id" : 2,
  62. "days" : 1.0,
  63. "mdays" : 0.0,
  64. "type" : "annualleave",
  65. "daytype" : "FullDay",
  66. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  67. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  68. "applieddate" : ISODate("2016-11-08T05:36:21.579Z"),
  69. "status" : "Processing",
  70. "approveddate" : Date(-62135596800000),
  71. "certificate" : [
  72. {
  73. "filename" : "india",
  74. "filetype" : ".zip",
  75. "filesize" : 1234
  76. },
  77. {
  78. "filename" : "france",
  79. "filetype" : ".zip",
  80. "filesize" : 1234
  81. }
  82. ]
  83. }
  84. ]
  85. }

你的Go代码如下:

  1. pipe3 := c.Pipe([]bson.M{
  2. {
  3. "$match": bson.M{
  4. "name": name,
  5. },
  6. },
  7. {
  8. "$unwind": "$leave",
  9. },
  10. {
  11. "$project": bson.M{
  12. "_id": false,
  13. "name": 1,
  14. "Id": "$leave.id",
  15. "Total": "$leave.total",
  16. "Days": "$leave.days",
  17. "Status": "$leave.status",
  18. },
  19. },
  20. })

问题是我不知道如何检索与特定请假相关的所有证书的所有信息。请注意,证书是一个至少有两个索引的数组。

我需要类似于以下输出:

  1. {
  2. "name": "John",
  3. "Id": "1",
  4. "Total": "10.0",
  5. "Days": "2.0",
  6. "Status": "Process",
  7. "Certificate": [
  8. {
  9. "filename": "certificate1",
  10. "filesize": "size1"
  11. },
  12. {
  13. "filename": "certificate2",
  14. "filesize": "size2"
  15. }
  16. ]
  17. }
  18. {
  19. "name": "John",
  20. "Id": "2",
  21. "Total": "8.0",
  22. "Days": "2.0",
  23. "Status": "Process",
  24. "Certificate": [
  25. {
  26. "filename": "certificate1",
  27. "filesize": "size1"
  28. },
  29. {
  30. "filename": "certificate2",
  31. "filesize": "size2"
  32. }
  33. ]
  34. }

是否可以使用$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.

  1. type (
  2. Employee struct {
  3. Name string
  4. Password string
  5. EmailAddress string
  6. Position string
  7. Gender string
  8. Nationality string
  9. Department string
  10. MaritalStatus string
  11. Approvedby string
  12. JoinDate time.Time
  13. ConfirmationDate time.Time
  14. EndDate time.Time
  15. Leave []*LeaveInfo
  16. }
  17. LeaveInfo struct {
  18. Total float64
  19. Id int
  20. Days float64
  21. From time.Time
  22. To time.Time
  23. Status string
  24. Certificate []*CertificateInfo
  25. }
  26. CertificateInfo struct {
  27. FileName string
  28. FileType string
  29. FileSize int
  30. }

The database structure is as follows

  1. {
  2. "_id" : ObjectId("58213e14927a62f3cf04e05b"),
  3. "name" : "string",
  4. "password" : "string",
  5. "emailaddress" : "string",
  6. "position" : "string",
  7. "gender" : "string",
  8. "maritalstatus" : "string",
  9. "approvedby" : "string",
  10. "nationality" : "german",
  11. "department" : "account",
  12. "joindate" : ISODate("2016-09-19T00:00:00.000Z"),
  13. "confirmationdate" : Date(-62135596800000),
  14. "enddate" : Date(-62135596800000),
  15. "Leave" : [
  16. {
  17. "total" : 20.0,
  18. "id" : 0,
  19. "days" : 0.0,
  20. "type" : "",
  21. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  22. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  23. "status" : "",
  24. "certificate" : [
  25. {
  26. "filename" : "malaysia",
  27. "filetype" : ".zip",
  28. "filesize" : 1234
  29. },
  30. {
  31. "filename" : "singapore",
  32. "filetype" : ".zip",
  33. "filesize" : 1234
  34. }
  35. ]
  36. },
  37. {
  38. "total" : 19.0,
  39. "id" : 1,
  40. "days" : 1.0,
  41. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  42. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  43. "applieddate" : ISODate("2016-11-08T02:53:38.902Z"),
  44. "status" : "Processing",
  45. "approveddate" : Date(-62135596800000),
  46. "certificate" : [
  47. {
  48. "filename" : "germany",
  49. "filetype" : ".zip",
  50. "filesize" : 1234
  51. },
  52. {
  53. "filename" : "england",
  54. "filetype" : ".zip",
  55. "filesize" : 1234
  56. }
  57. ]
  58. },
  59. {
  60. "total" : 18.0,
  61. "id" : 2,
  62. "days" : 1.0,
  63. "mdays" : 0.0,
  64. "type" : "annualleave",
  65. "daytype" : "FullDay",
  66. "from" : ISODate("2016-12-12T00:00:00.000Z"),
  67. "to" : ISODate("2016-12-12T00:00:00.000Z"),
  68. "applieddate" : ISODate("2016-11-08T05:36:21.579Z"),
  69. "status" : "Processing",
  70. "approveddate" : Date(-62135596800000),
  71. "certificate" : [
  72. {
  73. "filename" : "india",
  74. "filetype" : ".zip",
  75. "filesize" : 1234
  76. },
  77. {
  78. "filename" : "france",
  79. "filetype" : ".zip",
  80. "filesize" : 1234
  81. }
  82. ]
  83. }
  84. ]
  85. }

My code in golang is as follows

  1. pipe3 := c.Pipe([]bson.M{
  2. {
  3. "$match": bson.M{
  4. "name":name
  5. },
  6. },
  7. {
  8. "$unwind": "$leave",
  9. },
  10. {
  11. "$project": bson.M{
  12. "_id": false,
  13. "name": 1,
  14. "Id": "$leave.id",
  15. "Total": "$leave.total",
  16. "Days": "$leave.days",
  17. "Status": "$leave.status",
  18. },
  19. },
  20. })

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...

  1. I need an output similar to this.
  2. "name": "John",
  3. "Id": "1",
  4. "Total": "10.0",
  5. "Days": "2.0",
  6. "Status": "Process",
  7. "Certificate" : [
  8. {
  9. "filename":"certificate1",
  10. "filesize":"size1"
  11. },
  12. {
  13. "filename":"certificate2",
  14. "filesize":"size2"
  15. }
  16. ]
  17. "name": "John",
  18. "Id": "2",
  19. "Total": "8.0",
  20. "Days": "2.0",
  21. "Status": "Process",
  22. "Certificate" : [
  23. {
  24. "filename":"certificate1",
  25. "filesize":"size1"
  26. },
  27. {
  28. "filename":"certificate2",
  29. "filesize":"size2"
  30. }
  31. ]

Is this possible using project.or is there any other way to do this.Appreciate any help.Please.Thanks

答案1

得分: 1

根据您提供的文档结构示例,您只需通过$projectcertificate暴露在$project中,如下所示:

  1. pipeline := []bson.M{
  2. {"$match": bson.M{"name": "string"}},
  3. {"$unwind": "$Leave"},
  4. {"$project": bson.M{
  5. "_id": false,
  6. "name": 1,
  7. "Id": "$Leave.id",
  8. "Total": "$Leave.total",
  9. "Days": "$Leave.days",
  10. "Status": "$Leave.status",
  11. "Certificate": "$Leave.certificate"},
  12. },
  13. }
  14. pipe := collection.Pipe(pipeline)
  15. response := []bson.M{}
  16. err = pipe.All(&response)

由于您已经在Leave上使用了$unwind,每个请假请求都有单独的文档。上述聚合的输出将如下所示:

  1. {
  2. "name": "string",
  3. "Id": 0,
  4. "Total": 20,
  5. "Days": 0,
  6. "Status": "",
  7. "Certificate": [
  8. {
  9. "filename": "malaysia",
  10. "filetype": ".zip",
  11. "filesize": 1234
  12. },
  13. {
  14. "filename": "singapore",
  15. "filetype": ".zip",
  16. "filesize": 1234
  17. }
  18. ]
  19. },
  20. {
  21. "name": "string",
  22. "Id": 1,
  23. "Total": 19,
  24. "Days": 1,
  25. "Status": "Processing",
  26. "Certificate": [
  27. {
  28. "filename": "germany",
  29. "filetype": ".zip",
  30. "filesize": 1234
  31. },
  32. {
  33. "filename": "england",
  34. "filetype": ".zip",
  35. "filesize": 1234
  36. }
  37. ]
  38. },
  39. {
  40. "name": "string",
  41. "Id": 2,
  42. "Total": 18,
  43. "Days": 1,
  44. "Status": "Processing",
  45. "Certificate": [
  46. {
  47. "filename": "india",
  48. "filetype": ".zip",
  49. "filesize": 1234
  50. },
  51. {
  52. "filename": "france",
  53. "filetype": ".zip",
  54. "filesize": 1234
  55. }
  56. ]
  57. }

每个请假请求都有与之关联的相应证书。

英文:

Using on your document structure example above, you just have to expose certificate through $project as below:

  1. pipeline := []bson.M{
  2. {"$match": bson.M{"name":"string"}},
  3. {"$unwind": "$Leave"},
  4. {"$project": bson.M{
  5. "_id": false,
  6. "name": 1,
  7. "Id": "$Leave.id",
  8. "Total": "$Leave.total",
  9. "Days": "$Leave.days",
  10. "Status": "$Leave.status",
  11. "Certificate": "$Leave.certificate"},
  12. },
  13. }
  14. pipe := collection.Pipe(pipeline)
  15. response := []bson.M{}
  16. 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:

  1. {
  2. "name": "string",
  3. "Id": 0,
  4. "Total": 20,
  5. "Days": 0,
  6. "Status": "",
  7. "Certificate": [
  8. {
  9. "filename": "malaysia",
  10. "filetype": ".zip",
  11. "filesize": 1234
  12. },
  13. {
  14. "filename": "singapore",
  15. "filetype": ".zip",
  16. "filesize": 1234
  17. }
  18. ]
  19. },
  20. {
  21. "name": "string",
  22. "Id": 1,
  23. "Total": 19,
  24. "Days": 1,
  25. "Status": "Processing",
  26. "Certificate": [
  27. {
  28. "filename": "germany",
  29. "filetype": ".zip",
  30. "filesize": 1234
  31. },
  32. {
  33. "filename": "england",
  34. "filetype": ".zip",
  35. "filesize": 1234
  36. }
  37. ]
  38. },
  39. {
  40. "name": "string",
  41. "Id": 2,
  42. "Total": 18,
  43. "Days": 1,
  44. "Status": "Processing",
  45. "Certificate": [
  46. {
  47. "filename": "india",
  48. "filetype": ".zip",
  49. "filesize": 1234
  50. },
  51. {
  52. "filename": "france",
  53. "filetype": ".zip",
  54. "filesize": 1234
  55. }
  56. ]
  57. }

Where each leave request, has their own corresponding certificates associated with the leave.

huangapple
  • 本文由 发表于 2016年11月8日 11:36:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/40478523.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定