It includes src/main/java/com/example/countrysearch/service/CountryService.java
, using an Aggregation
The pipeline with the following steps:
-
Filtered Cities Addition: that filters cities based on whether their
from
field matches thesearchTerm
. The filtered array is then stored in a new field calledfilteredCities
. -
Conditional Logic for Final Cities: The pipeline checks whether
filteredCities
is empty (size is zero). If it is empty, a fallback occurs where the pipeline filters the cities based on thedetail
field set tonew_city
. The resulting array is stored in another new field calledfinalCities
. -
Output Formatting: The final operation in the pipeline projects (or selects) the fields that are required in the final output, such as
id
,name
, andfinalCities
. ThefinalCities
is renamed ascities
in the final output.
----------------------
| Input Document |
----------------------
|
|
v
------------------------
| Add 'filteredCities' | ---> Filter cities based on the 'from' field
------------------------
|
|
v
------------------------
| Conditional Logic | ---> Check if 'filteredCities' is empty; fallback to 'detail="new_city"'
------------------------
|
|
v
------------------------
| Output Formatting | ---> Project required fields ('id', 'name', 'finalCities')
------------------------
|
|
v
------------------------
| Final Output |
------------------------
package com.example.countrysearch.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.stereotype.Service;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.project;
import com.example.countrysearch.model.Country;
import java.util.List;
@Service
public class CountryService {
@Autowired
private MongoTemplate mongoTemplate;
public List<Country> findCountriesByCity(String searchTerm) {
// AggregationExpression for 'filteredCities'
AggregationExpression filterCitiesExpression = ArrayOperators.Filter.filter("cities")
.as("city")
.by(ComparisonOperators.Eq.valueOf("city.from").equalToValue(searchTerm));
// First addFields operation to add 'filteredCities'
AggregationOperation addFieldsFilteredCities = project("id", "name", "cities")
.and(filterCitiesExpression)
.as("filteredCities");
// AggregationExpression for conditional logic for 'finalCities'
AggregationExpression conditionalFinalCities = ConditionalOperators.when(
ComparisonOperators.Eq.valueOf(
ArrayOperators.Size.lengthOfArray("filteredCities")
).equalToValue(0)
)
.then(
ArrayOperators.Filter.filter("cities")
.as("city")
.by(
ComparisonOperators.Eq.valueOf("city.detail").equalToValue("new_city")
)
)
.otherwise("$filteredCities");
// Second addFields operation to add 'finalCities'
AggregationOperation addFieldsFinalCities = project("id", "name")
.and(conditionalFinalCities).as("finalCities");
// Final project operation to shape the output
AggregationOperation projectFinal = project("id", "name")
.and("finalCities").as("cities");
// Build the aggregation pipeline
Aggregation aggregation = Aggregation.newAggregation(
addFieldsFilteredCities,
addFieldsFinalCities,
projectFinal
);
// Execute the aggregation
AggregationResults<Country> result = mongoTemplate.aggregate(aggregation, "country", Country.class);
return result.getMappedResults();
}
}