diff --git a/src/controllers/content.controller.ts b/src/controllers/content.controller.ts index e35e111..d058fa1 100644 --- a/src/controllers/content.controller.ts +++ b/src/controllers/content.controller.ts @@ -901,6 +901,7 @@ export class contentController { queryData.cLevel, queryData.complexityLevel, queryData.graphemesMappedObj, + queryData.level_competency ); }else{ contentCollection = await this.contentService.getMechanicsContentData( @@ -908,7 +909,8 @@ export class contentController { queryData.mechanics_id, parseInt(Batch), queryData.language, - queryData.level_competency + queryData.level_competency, + queryData.tags ); } diff --git a/src/services/content.service.ts b/src/services/content.service.ts index a213512..bfcecb8 100644 --- a/src/services/content.service.ts +++ b/src/services/content.service.ts @@ -318,6 +318,7 @@ export class contentService { cLevel, complexityLevel, graphemesMappedObj, + level_competency = [] ): Promise { let nextTokenArr = [] if (tokenArr.length >= (limit * 2)) { @@ -1060,6 +1061,10 @@ export class contentService { query["tags"] = { $all: tags }; } + if (level_competency?.length > 0) { + query["level_complexity.level_competency"] = {$in:level_competency}; + } + const allTokenGraphemes = []; let contentData = []; @@ -1250,7 +1255,99 @@ export class contentService { }); } + // remove all criteria and get random content with level conpetency + if (contentData.length <= limit && level_competency?.length > 0) { + let randomContentQuery = { + contentSourceData: { + $elemMatch: { + }, + }, + contentType: contentType, + "level_complexity.level_competency": {$in:level_competency} + }; + + randomContentQuery.contentSourceData.$elemMatch['language'] = en_config.language_code; + + await this.content + .aggregate([ + { + $addFields: { + contentSourceData: { + $map: { + input: '$contentSourceData', + as: 'elem', + in: { + $mergeObjects: [ + '$$elem', + { + syllableCountArray: { + $objectToArray: '$$elem.syllableCountMap', + }, + }, + ], + }, + }, + }, + }, + }, + { + $match: randomContentQuery, + }, + { $sample: { size: limit - contentData.length } }, + ]) + .exec() + .then((doc) => { + for (const docEle of doc) { + if (contentData.length == 0 || !contentDataSet.has(docEle.contentId)) { + contentDataSet.add(docEle.contentId); + contentData.push(docEle); + } + } + }); + } + + if (contentData.length <= limit) { + if (level_competency?.length > 0) { + query["level_complexity.level_competency"] = { $exists: true } + } + await this.content + .aggregate([ + { + $addFields: { + contentSourceData: { + $map: { + input: '$contentSourceData', + as: 'elem', + in: { + $mergeObjects: [ + '$$elem', + { + syllableCountArray: { + $objectToArray: '$$elem.syllableCountMap', + }, + }, + ], + }, + }, + }, + }, + }, + { + $match: query, + }, + { $sample: { size: limit - contentData.length } }, + ]) + .exec() + .then((doc) => { + for (const docEle of doc) { + if (contentData.length == 0 || !contentDataSet.has(docEle.contentId)) { + contentDataSet.add(docEle.contentId); + contentData.push(docEle); + } + } + }); + } // remove all criteria and get random content with content type if (contentData.length <= limit) { @@ -1729,7 +1826,8 @@ export class contentService { mechanics_id, limit = 5, language, - levelCompetencyArr + levelCompetencyArr, + tags ) { let queries = []; const numLevels = levelCompetencyArr.length; @@ -1740,23 +1838,44 @@ export class contentService { if (numLevels > 0 && levelCompetencyArr !== undefined) { levelCompetencyArr.forEach((levelCompetency, levelCompetencyIndex) => { if (levelCompetencyIndex === 0) { - queries.push( - this.content.aggregate([ - { - $match: { - contentType: contentType, - language: language, - mechanics_data: { - $elemMatch: { mechanics_id: mechanics_id, language: language } - }, - "level_complexity.level_competency": levelCompetency - } - }, - { $sample: { size: splitLimit } } // Fetch for the first level - ]) - ); + if(tags.length > 0){ + queries.push( + this.content.aggregate([ + { + $match: { + contentType: contentType, + language: language, + mechanics_data: { + $elemMatch: { mechanics_id: mechanics_id, language: language } + }, + "level_complexity.level_competency": levelCompetency, + "tags":{ $all: tags } + } + }, + { $sample: { size: splitLimit } } // Fetch for the first level + ]) + ); + }else{ + queries.push( + this.content.aggregate([ + { + $match: { + contentType: contentType, + language: language, + mechanics_data: { + $elemMatch: { mechanics_id: mechanics_id, language: language } + }, + "level_complexity.level_competency": levelCompetency + } + }, + { $sample: { size: splitLimit } } // Fetch for the first level + ]) + ); + } } else { - let handleLimit = limit % 2 + let handleLimit = limit % 2; + + if(tags.length > 0){ queries.push( this.content.aggregate([ { @@ -1766,12 +1885,30 @@ export class contentService { mechanics_data: { $elemMatch: { mechanics_id: mechanics_id, language: language } }, - "level_complexity.level_competency": levelCompetency + "level_complexity.level_competency": levelCompetency, + "tags":{ $all: tags } } }, { $sample: { size: splitLimit - handleLimit } } // Fetch fewer items for other levels ]) ); + }else{ + queries.push( + this.content.aggregate([ + { + $match: { + contentType: contentType, + language: language, + mechanics_data: { + $elemMatch: { mechanics_id: mechanics_id, language: language } + }, + "level_complexity.level_competency": levelCompetency + } + }, + { $sample: { size: splitLimit - handleLimit } } // Fetch fewer items for other levels + ]) + ); + } } }); } @@ -1794,7 +1931,9 @@ export class contentService { // If results are less than the limit, fetch additional content from any level if (results.length < limit) { const remainingLimit = limit - results.length; - const additionalContent = await this.content.aggregate([ + let additionalContent; + if(tags.length > 0){ + additionalContent= await this.content.aggregate([ { $match: { contentType: contentType, @@ -1802,11 +1941,27 @@ export class contentService { mechanics_data: { $elemMatch: { mechanics_id: mechanics_id, language: language } }, - "level_complexity.level_competency": { $exists: true } + "level_complexity.level_competency": { $exists: true }, + "tags":{ $all: tags } } }, { $sample: { size: remainingLimit } } ]); + }else{ + additionalContent = await this.content.aggregate([ + { + $match: { + contentType: contentType, + language: language, + mechanics_data: { + $elemMatch: { mechanics_id: mechanics_id, language: language } + }, + "level_complexity.level_competency": { $exists: true } + } + }, + { $sample: { size: remainingLimit } } + ]); + } results = [...results, ...additionalContent]; } @@ -1821,8 +1976,23 @@ export class contentService { language: language, mechanics_data: { $elemMatch: { mechanics_id: mechanics_id, language: language } - }, - "level_complexity.level_competency": { $exists: false } + } + } + }, + { $sample: { size: remainingLimit } } + ]); + + results = [...results, ...fallbackContent]; + } + + // If results are still less than the limit, fetch content without mechanics_data + if (results.length < limit) { + const remainingLimit = limit - results.length; + const fallbackContent = await this.content.aggregate([ + { + $match: { + contentType: contentType, + language: language, } }, { $sample: { size: remainingLimit } } @@ -1836,11 +2006,13 @@ export class contentService { wordsArr.map((content) => { const { mechanics_data } = content; + if(mechanics_data){ const mechanicData = mechanics_data.find( (mechanic) => {return mechanic.mechanics_id === mechanics_id} ); content.mechanics_data = []; content.mechanics_data.push(mechanicData); + } return content; });