Skip to content

Commit

Permalink
refactor: extract search process to class
Browse files Browse the repository at this point in the history
  • Loading branch information
Chinlinlee committed Nov 12, 2022
1 parent 3c10036 commit c056dd3
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 63 deletions.
73 changes: 10 additions & 63 deletions api/FHIRApiService/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const {
SearchParameterCreator,
UnknownSearchParameterError
} = require("./search/searchParameterCreator");
const { SearchProcessor } = require("./search/searchProcessor");
const xmlFormatter = require('xml-formatter');
/**
*
Expand Down Expand Up @@ -67,70 +68,16 @@ module.exports = async function (req, res, resourceType, paramsSearch) {
logger.info(loggerInfo);

try {
let docs;
let isChain = _.get(queryParameter, "isChain", false);
let count = 0;

if (isChain) {
let aggregateQuery = [];
if (_.get(queryParameter, "$and", []).length > 0) {
let selfMatch = {
"$match": {
$and: queryParameter.$and
}
};
aggregateQuery.push(selfMatch);
}
aggregateQuery.push(...queryParameter["chain"].flat());

aggregateQuery.push({
$group: {
"_id": "$_id",
"groupItem": {
"$first": "$$ROOT"
}
}
});
aggregateQuery.push({
"$replaceRoot": {
"newRoot": "$groupItem"
}
});

aggregateQuery.push({$skip: paginationSkip});
aggregateQuery.push({$limit: paginationLimit});

docs = await mongodb[resourceType].aggregate(aggregateQuery).exec();

if (_total !== "none") {
aggregateQuery.push({ "$count": "totalDocs" });
let totalDocs = count = await mongodb[resourceType].aggregate(aggregateQuery).exec();
count = _.get(totalDocs, "0.totalDocs", 0);
}

} else {
docs = await mongodb[resourceType].find(queryParameter).
limit(paginationLimit).
skip(paginationSkip).
sort({
_id: -1
}).
exec();
}

if (_total !== "none") {
if (_.isEmpty(queryParameter)) {

if (_total === "estimate") {
count = await mongodb[resourceType].estimatedDocumentCount();
} else if (_total === "accurate"){
count = await mongodb[resourceType].countDocuments();
}

} else if (!isChain) {
count = await mongodb[resourceType].countDocuments(queryParameter);
}
}
let searchProcessor = new SearchProcessor({
resourceType: resourceType,
isChain: isChain,
query: queryParameter,
skip: paginationSkip,
limit: paginationLimit,
totalMode: _total
});
let { docs, count } = await searchProcessor.search();

if (isChain) {
docs = docs.map(v => {
Expand Down
154 changes: 154 additions & 0 deletions api/FHIRApiService/search/searchProcessor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* The class for executing "search"
* @author Chin-Lin Lee <[email protected]>
*/

const mongoose = require("mongoose");
const _ = require("lodash");

/**
* @typedef SearchProcessorOptions
* @property {string} resourceType
* @property {boolean} isChain
* @property {Object} query
* @property {number} skip
* @property {number} limit
* @property {string} totalMode
*/

/**
* @typedef SearchResult
* @property {Object} docs
* @property {number} count
*/

class SearchProcessor {
/**
* @param {SearchProcessorOptions} options
*/
constructor(options) {
this.resourceType = options.resourceType;
this.isChain = options.isChain;
this.query = options.query;
this.skip = options.skip;
this.limit = options.limit;
this.totalMode = options.totalMode;
}

/**
*
* @return {SearchResult}
*/
async search() {
try {

if (this.isChain) {
return await this.searchChain_();
} else {
return await this.searchNormal_();
}

} catch (e) {
throw e;
}
}

/**
* @private
* @return {SearchResult}
*/
async searchChain_() {
try {
let aggregateQuery = [];
if (_.get(this.query, "$and", []).length > 0) {
let selfMatch = {
"$match": {
$and: this.query.$and
}
};
aggregateQuery.push(selfMatch);
}
aggregateQuery.push(...this.query["chain"].flat());

aggregateQuery.push({
$group: {
"_id": "$_id",
"groupItem": {
"$first": "$$ROOT"
}
}
});
aggregateQuery.push({
"$replaceRoot": {
"newRoot": "$groupItem"
}
});

aggregateQuery.push({ $skip: this.skip });
aggregateQuery.push({ $limit: this.limit });

let docs = await mongoose.model(this.resourceType)
.aggregate(aggregateQuery)
.exec();

let count = 0;
if (this.totalMode !== "none") {
aggregateQuery.push({ "$count": "totalDocs" });
let totalDocs = count = await mongoose.model(this.resourceType)
.aggregate(aggregateQuery)
.exec();

count = _.get(totalDocs, "0.totalDocs", 0);
}

return {
docs: docs,
count: count
};
} catch (e) {
throw e;
}
}

/**
* @private
* @return {SearchResult}
*/
async searchNormal_() {
try {
let docs = await mongoose.model(this.resourceType).find(this.query)
.limit(this.limit)
.skip(this.skip)
.sort({
_id: 1
})
.exec();


let count = 0;
if (this.totalMode !== "none") {
if (_.isEmpty(this.query)) {

if (this.totalMode === "estimate") {
count = await mongoose.model(this.resourceType).estimatedDocumentCount();
} else if (this.totalMode === "accurate") {
count = await mongoose.model(this.resourceType).countDocuments();
}

} else {
count = await mongoose.model(this.resourceType).countDocuments(this.query);
}
}

return {
docs: docs,
count: count
};
} catch (e) {
throw e;
}

}
}

module.exports.SearchProcessor = SearchProcessor;

0 comments on commit c056dd3

Please sign in to comment.