Как отфильтровать список DTO на основе списка критериев поиска?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как отфильтровать список DTO на основе списка критериев поиска?

Сообщение Anonymous »

Я пытаюсь реализовать фильтрацию по списку сотрудниковDTO. У меня есть список SearchCritera, который я хочу наложить на список для фильтрации. Вот структуры классов.

Код: Выделить всё

public class EmployeeDTO {
private String id;
private String employeeId;
private String email;
private String phone;
private String firstName;
private String lastName;
private String middleName;
private LocalDate dob;
private Map details; // for storing dynamic nested data
}

public class SearchCriteria {
private String key;
private String value;
private SearchCondition condition;
private SearchOperation operation;
}

public enum SearchCondition {
EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUALS, LESS_THAN_OR_EQUALS
}

public enum SearchOperation {
AND, OR, NOT
}
Вы можете ожидать, что список SearchCriteria будет чем-то вроде этого:

Код: Выделить всё

[
{
"key": "education.degree",
// would reside in details.education.degree where education is an array of {degree, city}
"value": "BBA",
"condition": "EQUALS"
},
{
"key": "education.degree",
"value": "MBAA",
"condition": "EQUALS",
"operation": "AND"
},
{
"key": "education.degree",
"value": "BA",
"condition": "EQUALS",
"operation": "OR"
},
{
"key": "middle_name",
"value": "Anne",
"condition": "EQUALS",
"operation": "NOT"
}
]
Это то, что я реализовал для фильтрации списка сотрудников. Но я получаю неточные результаты, основанные на этом методе фильтрации. Должно быть, я где-то ошибаюсь.

Код: Выделить всё

public class EmployeeFilter {
private static final Logger log = LoggerFactory.getLogger(EmployeeFilter.class);
private static final String OUTPUT_1 = "output_1";
private static final String OUTPUT_2 = "output_2";

public Map processNode(List employees, List searchCriteria) {
Map filteredEmployees = filterEmployees(employees, searchCriteria);

JSONObject validEmployeesJson = new JSONObject();
validEmployeesJson.put(Constants.EMPLOYEES, filteredEmployees.get("valid"));

JSONObject invalidEmployeesJson = new JSONObject();
invalidEmployeesJson.put(Constants.EMPLOYEES, filteredEmployees.get("invalid"));

return Map.of(
OUTPUT_1, validEmployeesJson,
OUTPUT_2, invalidEmployeesJson
);
}

private Map filterEmployees(List employees, List searchCriteria) {
Map partitionedEmployees = employees.stream()
.collect(Collectors.partitioningBy(e -> isEmployeeMatchingSearchCriteria(e, searchCriteria)));

return Map.of(
"valid", partitionedEmployees.getOrDefault(true, Collections.emptyList()),
"invalid", partitionedEmployees.getOrDefault(false, Collections.emptyList())
);
}

private boolean isEmployeeMatchingSearchCriteria(EmployeeDTO employee, List searchCriteria) {
boolean result = true;

for (SearchCriteria criterion : searchCriteria) {
boolean match = evaluateCondition(employee, criterion);

SearchOperation currentOperation = criterion.getOperation();
if (currentOperation == null) currentOperation = SearchOperation.AND;

result = switch(currentOperation) {
case AND -> result && match;
case OR -> result || match;
case NOT -> !match;
};
}

return result;
}

private boolean evaluateCondition(EmployeeDTO employee, SearchCriteria criterion) {
String key = criterion.getKey();
String val = criterion.getValue();
SearchCondition condition = criterion.getCondition();

Object employeeValue = getValue(employee, key);

if(employeeValue == null) return false;

switch (condition) {
case EQUALS:
if (employeeValue instanceof List) {
List list = (List) employeeValue;
return list.stream().anyMatch(item -> item.equals(val));
}
return employeeValue.equals(val);

case CONTAINS:
return employeeValue.toString().contains(val);
case STARTS_WITH:
return employeeValue.toString().startsWith(val);
case ENDS_WITH:
return employeeValue.toString().endsWith(val);
case GREATER_THAN:
return compareValues(employeeValue, val) > 0;
case LESS_THAN:
return compareValues(employeeValue, val) <  0;
case GREATER_THAN_OR_EQUALS:
return compareValues(employeeValue, val) >= 0;
case LESS_THAN_OR_EQUALS:
return compareValues(employeeValue, val) 

Подробнее здесь: [url]https://stackoverflow.com/questions/79256018/how-to-filter-a-list-of-dtos-based-on-a-list-of-search-criteria[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»