@@ -2,44 +2,93 @@ export const softwareDetailAggregationPipeline = (softwareName: string): any[] =
22 {
33 $match : { softwareName }
44 } ,
5+
56 {
6- $sort : { _id : - 1 } // Sort documents by their _id in descending order
7+ $addFields : {
8+ creationDate : { $toDate : "$_id" }
9+ }
10+ } ,
11+
12+ {
13+ $sort : { creationDate : - 1 }
14+ } ,
15+
16+ // Group all documents and add the latest document as a new field to all documents
17+ {
18+ $group : {
19+ _id : null ,
20+ documents : { $push : "$$ROOT" } ,
21+ latestDocumentRecord : { $first : "$$ROOT" } // Since the documents are sorted, $first will be the latest
22+ }
23+ } ,
24+
25+ {
26+ $unwind : "$documents"
27+ } ,
28+
29+ {
30+ $addFields : {
31+ "documents.latestDocumentRecord" : "$latestDocumentRecord"
32+ }
33+ } ,
34+
35+ {
36+ $replaceRoot : { newRoot : "$documents" }
737 } ,
38+
839 {
940 $project : {
10- objectId : "$_id" , // Use the actual _id field from the document
41+ objectId : "$_id" ,
1142 softwareName : 1 ,
1243 compliance : 1 ,
1344 logo : 1 ,
1445 website : 1 ,
1546 documentation : 1 ,
1647 pointOfContact : 1 ,
17- status : 1
48+ status : 1 ,
49+ creationDate : 1 ,
50+ latestDocumentRecord : 1
1851 }
1952 } ,
53+
2054 {
2155 $unwind : { path : "$compliance" , preserveNullAndEmptyArrays : true }
2256 } ,
57+
58+ // Transform the compliance.bbDetails object into an array and add necessary fields
2359 {
2460 $addFields : {
2561 "compliance.bbDetailsArray" : {
2662 $map : {
2763 input : { $ifNull : [ { $objectToArray : "$compliance.bbDetails" } , [ ] ] } ,
2864 as : "detail" ,
2965 in : {
30- "bbName" : "$$detail.k" ,
31- "bbVersion" : "$$detail.v.bbVersion" ,
32- "requirements" : "$$detail.v.requirementSpecificationCompliance" ,
33- "interface" : "$$detail.v.interfaceCompliance" ,
34- "deploymentCompliance" : "$$detail.v.deploymentCompliance"
66+ bbName : "$$detail.k" ,
67+ bbVersion : "$$detail.v.bbVersion" ,
68+ requirements : "$$detail.v.requirementSpecificationCompliance" ,
69+ interface : "$$detail.v.interfaceCompliance" ,
70+ deploymentCompliance : "$$detail.v.deploymentCompliance" ,
71+ creationDate : {
72+ $toDate : {
73+ $convert : {
74+ input : { $substr : [ "$$detail.v.bbVersion" , 0 , 8 ] } ,
75+ to : "long" ,
76+ onError : null ,
77+ onNull : null
78+ }
79+ }
80+ }
3581 }
3682 }
3783 }
3884 }
3985 } ,
86+
4087 {
4188 $unwind : { path : "$compliance.bbDetailsArray" , preserveNullAndEmptyArrays : true }
4289 } ,
90+
91+ // Group by software name, software version, and building block name
4392 {
4493 $group : {
4594 _id : {
@@ -52,17 +101,47 @@ export const softwareDetailAggregationPipeline = (softwareName: string): any[] =
52101 bbVersion : { $ifNull : [ "$compliance.bbDetailsArray.bbVersion" , "N/A" ] } ,
53102 requirements : { $ifNull : [ "$compliance.bbDetailsArray.requirements" , { } ] } ,
54103 interface : { $ifNull : [ "$compliance.bbDetailsArray.interface" , { } ] } ,
55- deploymentCompliance : { $ifNull : [ "$compliance.bbDetailsArray.deploymentCompliance" , { } ] }
104+ createdDate : "$creationDate" ,
105+ deploymentCompliance : { $ifNull : [ "$compliance.bbDetailsArray.deploymentCompliance" , { } ] } ,
106+ documentId : "$objectId" // Capture the _id of the document for this bbVersion
56107 }
57108 } ,
58- logo : { $first : "$logo" } ,
59- website : { $first : "$website" } ,
60- documentation : { $first : "$documentation" } ,
61- pointOfContact : { $first : "$pointOfContact" } ,
62- status : { $first : "$status" } ,
63- objectId : { $first : "$objectId" }
109+ latestRecord : { $first : "$$ROOT" } ,
110+ latestDocumentRecord : { $first : "$latestDocumentRecord" } ,
111+ topDocumentId : { $first : "$objectId" } // Store the _id of the first (latest) document
64112 }
65113 } ,
114+
115+ // Unwind the bbVersions array
116+ {
117+ $unwind : "$bbVersions"
118+ } ,
119+
120+ // Group by software name, version, and building block name
121+ {
122+ $group : {
123+ _id : {
124+ softwareName : "$_id.softwareName" ,
125+ softwareVersion : "$_id.softwareVersion" ,
126+ bbName : "$_id.bbName"
127+ } ,
128+ bbVersions : {
129+ $push : {
130+ bbVersion : "$bbVersions.bbVersion" ,
131+ requirements : "$bbVersions.requirements" ,
132+ interface : "$bbVersions.interface" ,
133+ deploymentCompliance : "$bbVersions.deploymentCompliance" ,
134+ creationDate : "$bbVersions.creationDate" ,
135+ documentId : "$bbVersions.documentId" // Preserve the documentId
136+ }
137+ } ,
138+ latestRecord : { $first : "$latestRecord" } ,
139+ latestDocumentRecord : { $first : "$latestDocumentRecord" } ,
140+ topDocumentId : { $first : "$bbVersions.documentId" } // Capture the documentId of the top bbVersion
141+ }
142+ } ,
143+
144+ // Group by software name and version, and gather building block details
66145 {
67146 $group : {
68147 _id : {
@@ -72,38 +151,148 @@ export const softwareDetailAggregationPipeline = (softwareName: string): any[] =
72151 bbDetails : {
73152 $push : {
74153 bbName : "$_id.bbName" ,
75- bbVersions : "$bbVersions"
154+ bbVersions : "$bbVersions" , // This includes the preserved documentId within each bbVersion
155+ topDocumentId : "$topDocumentId" // Capture the topDocumentId for this bbDetail
156+ }
157+ } ,
158+ latestRecord : { $first : "$latestRecord" } ,
159+ latestDocumentRecord : { $first : "$latestDocumentRecord" }
160+ }
161+ } ,
162+
163+ // Project the final set of fields, including maximum creation date
164+ {
165+ $project : {
166+ _id : 1 ,
167+ bbDetails : {
168+ $map : {
169+ input : "$bbDetails" ,
170+ as : "detail" ,
171+ in : {
172+ bbName : "$$detail.bbName" ,
173+ bbVersions : "$$detail.bbVersions" ,
174+ topDocumentId : "$$detail.topDocumentId" // Include topDocumentId within each bbDetails entry
175+ }
76176 }
77177 } ,
78- logo : { $first : "$logo" } ,
79- website : { $first : "$website" } ,
80- documentation : { $first : "$documentation" } ,
81- pointOfContact : { $first : "$pointOfContact" } ,
82- status : { $first : "$status" } ,
83- objectId : { $first : "$objectId" }
178+ logo : "$latestRecord.logo" ,
179+ website : "$latestRecord.website" ,
180+ documentation : "$latestRecord.documentation" ,
181+ pointOfContact : "$latestRecord.pointOfContact" ,
182+ status : "$latestRecord.status" ,
183+ objectId : "$latestRecord.objectId" ,
184+ maxCreatedDate : { $max : "$bbDetails.bbVersions.createdDate" } ,
185+ latestDocumentRecord : 1
84186 }
85187 } ,
188+
189+ // Group by software name and collect all compliance details
86190 {
87191 $group : {
88192 _id : "$_id.softwareName" ,
89193 compliance : {
90194 $push : {
91195 softwareVersion : "$_id.softwareVersion" ,
92196 bbDetails : "$bbDetails" ,
93- _id : "$objectId" // Add _id at the same level as softwareVersion
197+ createdDate : "$maxCreatedDate"
94198 }
95199 } ,
96- logo : { $first : "$logo" } ,
97- website : { $first : "$website" } ,
98- documentation : { $first : "$documentation" } ,
99- pointOfContact : { $first : "$pointOfContact" } ,
100- status : { $first : "$status" } ,
101- objectId : { $first : "$objectId" }
200+ logo : { $first : "$latestDocumentRecord.logo" } ,
201+ website : { $first : "$latestDocumentRecord.website" } ,
202+ documentation : { $first : "$latestDocumentRecord.documentation" } ,
203+ pointOfContact : { $first : "$latestDocumentRecord.pointOfContact" } ,
204+ status : { $first : "$latestDocumentRecord.status" } ,
205+ objectId : { $first : "$latestDocumentRecord.objectId" } ,
206+ latestDocumentRecord : { $first : "$latestDocumentRecord" }
207+ }
208+ } ,
209+
210+ // Add fields to compliance and sort building blocks alphabetically, with "N/A" values at the end
211+ {
212+ $addFields : {
213+ compliance : {
214+ $map : {
215+ input : {
216+ $sortArray : {
217+ input : "$compliance" ,
218+ sortBy : { softwareVersion : 1 } // Ensure compliance is sorted by softwareVersion in ascending order
219+ }
220+ } ,
221+ as : "comp" ,
222+ in : {
223+ softwareVersion : "$$comp.softwareVersion" ,
224+ bbDetails : {
225+ $let : {
226+ vars : {
227+ detailsWithSortKey : {
228+ $map : {
229+ input : "$$comp.bbDetails" ,
230+ as : "detail" ,
231+ in : {
232+ bbName : "$$detail.bbName" ,
233+ bbVersions : "$$detail.bbVersions" ,
234+ _id : "$$detail.topDocumentId" ,
235+ sortKey : {
236+ $cond : {
237+ if : { $eq : [ "$$detail.bbName" , "N/A" ] } ,
238+ then : 1 , // "N/A" values get a higher sortKey to appear at the end
239+ else : 0
240+ }
241+ }
242+ }
243+ }
244+ }
245+ } ,
246+ in : {
247+ $sortArray : {
248+ input : "$$detailsWithSortKey" ,
249+ sortBy : { sortKey : 1 , bbName : 1 } // Sort alphabetically with "N/A" last
250+ }
251+ }
252+ }
253+ } ,
254+ _id : "$$comp._id" ,
255+ createdDate : "$$comp.createdDate"
256+ }
257+ }
258+ }
102259 }
103260 } ,
261+
262+ {
263+ $sort : { "latestRecord.creationDate" : - 1 }
264+ } ,
265+
104266 {
105- $sort : { _id : - 1 } // Sort documents by their _id in descending order
267+ $limit : 1
268+ } ,
269+
270+ // Extract _id from the top object of bbDetails and include it at the same level as softwareVersion and createdDate
271+ {
272+ $addFields : {
273+ compliance : {
274+ $map : {
275+ input : "$compliance" ,
276+ as : "comp" ,
277+ in : {
278+ _id : {
279+ $let : {
280+ vars : {
281+ topDetail : { $arrayElemAt : [ "$$comp.bbDetails" , 0 ] } // Get the top object from bbDetails
282+ } ,
283+ in : "$$topDetail._id" // Extract _id from the top object
284+ }
285+ } ,
286+ softwareVersion : "$$comp.softwareVersion" ,
287+ createdDate : "$$comp.createdDate" ,
288+ bbDetails : "$$comp.bbDetails" // Keep the bbDetails array as is
289+ }
290+ }
291+ }
292+ }
106293 } ,
294+
295+ // Final projection of the required fields
107296 {
108297 $project : {
109298 _id : "$objectId" ,
@@ -113,10 +302,7 @@ export const softwareDetailAggregationPipeline = (softwareName: string): any[] =
113302 website : 1 ,
114303 documentation : 1 ,
115304 pointOfContact : 1 ,
116- status : 1
305+ status : 1 ,
117306 }
118- } ,
119- {
120- $limit : 1 // Return the latest matching object
121307 }
122308] ;
0 commit comments