@@ -17,18 +17,45 @@ const wholeReferenceResponse = handler({
1717 const database = await getDatabase ( request ) ;
1818 // Get the requested reference configuration
1919 const referenceName = request . params . reference ;
20+ const reference = REFERENCES [ referenceName ] ;
21+ if ( ! reference ) return {
22+ headerError : NOT_FOUND ,
23+ error : `Unknown reference "${ referenceName } ". Available references: ${ availableReferences } `
24+ } ;
25+ // Get a list with all reference ids which are to be returned according to the available projects
26+ // Note that less references are to be returned if this is the production API
27+ const projectQuery = database . getProjectQuery ( ) ;
28+ const distinctResult = await database . projects . distinct (
29+ reference . projectIdsField , projectQuery ) ;
30+ let availableReferenceIds = new Set ( distinctResult ) ;
31+ // Get the number of references to be matched with the current query
32+ const referencesCount = availableReferenceIds . length ;
33+ // Set the target mongo collection
34+ const collection = database [ referenceName ] ;
2035 // Get the requested query, if any
2136 const query = request . query . query ;
22- const parsedQuery = ( query && JSON . parse ( query ) ) || { } ;
37+ // If a query was passed then filter references and get the remaining reference ids
38+ if ( query ) {
39+ // Parse the query
40+ const parsedQuery = JSON . parse ( query ) ;
41+ // Query all references and get only their reference ids
42+ const cursor = await collection . find ( parsedQuery )
43+ . project ( { _id : false , [ reference . idField ] : true } ) ;
44+ const filteredReferenceIds = new Set ( cursor . map ( ref => ref [ reference . idField ] ) ) ;
45+ // Keep only reference ids which are both available and filtered
46+ availableReferenceIds = availableReferenceIds . intersection ( filteredReferenceIds ) ;
47+ }
48+ // Sort the available reference ids
49+ const sortedReferenceIds = Array . from ( availableReferenceIds ) . sort ( ) ;
2350 // Check if we are to return only the available ids
2451 // If so then there is no need for pagination or projections
2552 // LORE: This was the original behaviour of this endpoint
2653 const justIds = request . query . justids ;
2754 const returnJustIds = justIds !== undefined && justIds !== 'false' ;
28- if ( returnJustIds ) return await database . getReferenceAvailableIds ( referenceName , parsedQuery ) ;
55+ if ( returnJustIds ) return sortedReferenceIds ;
2956 // Otherwise we must paginate and handle possible projections
3057 // Set the projection object for the mongo query
31- const projector = { } ;
58+ const projector = { _id : false } ;
3259 // Handle when it is a mongo projection itself
3360 // Note that when a projection is requested the project data is not formatted
3461 let projection = request . query . projection ;
@@ -46,29 +73,20 @@ const wholeReferenceResponse = handler({
4673 Object . assign ( projector , objectProjection ) ;
4774 }
4875 }
49- // Set the target mongo collection
50- const collection = database [ referenceName ] ;
51- // Get the number of references to be matched with the current query
52- const referencesCount = await collection . countDocuments ( parsedQuery ) ;
53- // Finally, perform the mongo query
54- // WARNING: If the query is wrong it will not make the code fail until the cursor in consumed
55- // e.g. cursor.toArray()
56- const cursor = await collection . find ( parsedQuery ) . project ( projector ) ;
57- // Handle the pagination
58- // Get the limit of references to be returned
76+ // Do the pagination manually
77+ // Get the skip (page) and limit of references to be returned
5978 // If the query has no limit then use a defualt value
6079 // If the query limit is grater than the limit then set it as the limit
6180 // If the limit is negative (which makes not sense) it is set to 0
6281 // This is defined in the src/server/index.js script
63- let limit = request . query . limit ;
82+ const skip = request . skip ;
83+ const limit = request . query . limit ; // The limit will never be greater than 100
84+ const paginatedReferenceIds = sortedReferenceIds . splice ( skip , limit ) ;
85+ const paginatedReferencesQuery = { [ reference . idField ] : { $in : paginatedReferenceIds } } ;
86+ // Finally, perform the final mongo query
87+ const cursor = await collection . find ( paginatedReferencesQuery ) . project ( projector ) ;
6488 // Finally consume the cursor
65- const references = await cursor
66- // Avoid the first results when a page is provided in the request (URL)
67- . skip ( request . skip )
68- // Avoid the last results when a limit is provided in the request query (URL)
69- . limit ( limit )
70- // Changes the type from Cursor into Array, then saving data in memory
71- . toArray ( ) ;
89+ const references = await cursor . toArray ( ) ;
7290 return { referencesCount, references } ;
7391 }
7492} ) ;
0 commit comments