@@ -20,9 +20,9 @@ class CountryQueryService {
2020 required DataRepository <Country > countryRepository,
2121 required Logger log,
2222 Duration cacheDuration = const Duration (minutes: 15 ),
23- }) : _countryRepository = countryRepository,
24- _log = log,
25- _cacheDuration = cacheDuration {
23+ }) : _countryRepository = countryRepository,
24+ _log = log,
25+ _cacheDuration = cacheDuration {
2626 _cleanupTimer = Timer .periodic (const Duration (minutes: 5 ), (_) {
2727 _cleanupCache ();
2828 });
@@ -35,7 +35,7 @@ class CountryQueryService {
3535 final Duration _cacheDuration;
3636
3737 final Map <String , ({PaginatedResponse <Country > data, DateTime expiry})>
38- _cache = {};
38+ _cache = {};
3939 Timer ? _cleanupTimer;
4040 bool _isDisposed = false ;
4141
@@ -123,10 +123,34 @@ class CountryQueryService {
123123 final pipeline = < Map <String , dynamic >> [];
124124 final compoundMatchStages = < Map <String , dynamic >> [];
125125
126- // --- Stage 1: Initial Match for active status (if applicable) ---
126+ // --- Stage 1: Initial Match for active status, text search, and other filters ---
127127 // All countries should be active by default for these queries
128128 compoundMatchStages.add ({'status' : ContentStatus .active.name});
129129
130+ // Handle `q` (text search) filter
131+ final qValue = filter['q' ];
132+ if (qValue is String && qValue.isNotEmpty) {
133+ compoundMatchStages.add ({
134+ r'$text' : {r'$search' : qValue},
135+ });
136+ }
137+
138+ // Handle other standard filters
139+ filter.forEach ((key, value) {
140+ if (key != 'q' &&
141+ key != 'hasActiveSources' &&
142+ key != 'hasActiveHeadlines' ) {
143+ compoundMatchStages.add ({key: value});
144+ }
145+ });
146+
147+ // Combine all compound match stages and add to pipeline first for efficiency
148+ if (compoundMatchStages.isNotEmpty) {
149+ pipeline.add ({
150+ r'$match' : {r'$and' : compoundMatchStages},
151+ });
152+ }
153+
130154 // --- Stage 2: Handle `hasActiveSources` filter ---
131155 if (filter['hasActiveSources' ] == true ) {
132156 // This lookup uses a sub-pipeline to filter for active sources *before*
@@ -183,31 +207,7 @@ class CountryQueryService {
183207 });
184208 }
185209
186- // --- Stage 4: Handle `q` (text search) filter ---
187- final qValue = filter['q' ];
188- if (qValue is String && qValue.isNotEmpty) {
189- compoundMatchStages.add ({
190- r'$text' : {r'$search' : qValue},
191- });
192- }
193-
194- // --- Stage 5: Handle other standard filters ---
195- filter.forEach ((key, value) {
196- if (key != 'q' &&
197- key != 'hasActiveSources' &&
198- key != 'hasActiveHeadlines' ) {
199- compoundMatchStages.add ({key: value});
200- }
201- });
202-
203- // Combine all compound match stages
204- if (compoundMatchStages.isNotEmpty) {
205- pipeline.add ({
206- r'$match' : {r'$and' : compoundMatchStages},
207- });
208- }
209-
210- // --- Stage 6: Project to original Country structure and ensure uniqueness ---
210+ // --- Stage 4: Project to original Country structure and ensure uniqueness ---
211211 // After lookups and matches, we might have duplicate countries if they
212212 // matched multiple sources/headlines. We need to group them back to unique countries.
213213 pipeline.add ({
@@ -222,7 +222,7 @@ class CountryQueryService {
222222 },
223223 });
224224
225- // --- Stage 7 : Sorting ---
225+ // --- Stage 5 : Sorting ---
226226 if (sort != null && sort.isNotEmpty) {
227227 final sortStage = < String , dynamic > {};
228228 for (final option in sort) {
@@ -231,7 +231,7 @@ class CountryQueryService {
231231 pipeline.add ({r'$sort' : sortStage});
232232 }
233233
234- // --- Stage 8 : Pagination (Skip and Limit) ---
234+ // --- Stage 6 : Pagination (Skip and Limit) ---
235235 if (pagination? .cursor != null ) {
236236 // For cursor-based pagination, we'd typically need a more complex
237237 // aggregation that sorts by the cursor field and then skips.
@@ -247,6 +247,7 @@ class CountryQueryService {
247247 pipeline.add ({r'$limit' : pagination! .limit! + 1 });
248248 }
249249
250+ // --- Stage 7: Final Projection ---
250251 // Project to match the Country model's JSON structure if necessary
251252 // (e.g., if _id was used, map it back to id)
252253 pipeline.add ({
0 commit comments