Вопрос или проблема
У меня есть запрос mongoDB, который использует агрегацию. Я применяю проекцию, а затем разворачиваю.
ProjectionOperation projectionPreUnwind = Aggregation.project(Fields.from(Fields.field("result.detections.reference.control", "result.detections.reference.control")));
UnwindOperation unwindOpn = Aggregation.unwind("result.detections");
Aggregation aggregation = Aggregation.newAggregation(projectionPreUnwind, unwindOpn);
LOGGER.info(" агрегация {}", aggregation);
AggregationResults<String> detectionsDataAggr = mongoTemplate.aggregate(aggregation, CASES_COLLECTION, String.class);
Результат кода вызывает ошибку
2024-10-23 16:48:00.097 INFO B33543D --- [nio-8082-exec-9] .c.c.s.d.r.c.i.MyRepoImpl : ВХОД В агрегацию [!!!org.springframework.data.mongodb.core.aggregation.Aggregation@3fee8ffe=>java.lang.IllegalArgumentException: Неверная ссылка 'result.detections'!!!!]
2024-10-23 16:48:03.158 ERROR B33543D — [nio-8082-exec-9] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() для сервлета [dispatcherServlet] в контексте с путем [] выдало исключение [Обработка запроса завершилась неудачей; вложенное исключение java.lang.IllegalArgumentException: Неверная ссылка ‘result.detections’!] с коренной причиной
java.lang.IllegalArgumentException: Неверная ссылка ‘result.detections’!
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:114)
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:77)
at org.springframework.data.mongodb.core.aggregation.UnwindOperation.toDocument(UnwindOperation.java:95)
Пример файла JSON
{
"result": {
"aiModel": "",
"detections": [
{
"aiStatus": "PASS",
"reference": {
"attribute": "TEST",
"control": "C Test"
}
},
{
"aiStatus": "FAIL",
"reference": {
"attribute": "TES22T",
"control": "C Test"
}
}
]
}
}
Ответ или решение
Проблема с запросом MongoDB: Ошибка Unwind
Введение
Ваша проблема с запросом MongoDB связана с использованием операции агрегации, где вы применяете проекцию, а затем пытаетесь использовать метод unwind
. При этом возникает ошибка, указывающая на недопустимую ссылку на поле result.detections
. Давайте детально рассмотрим, как решить эту проблему.
Анализ проблемы
Согласно предоставленному коду, вы создаёте проекцию для извлечения поля result.detections.reference.control
, однако затем в операции unwind
указываете путь к полю result.detections
. Ошибка IllegalArgumentException: Invalid reference 'result.detections'
свидетельствует о том, что MongoDB не может найти указанное поле.
-
Проекция: Ваша проекция ограничивает вывод только полем
result.detections.reference.control
. Из-за этого MongoDB не знает о структуре массиваresult.detections
, которая остается вне контекста после выполнения проекции. -
Unwind: Операция
unwind
пытается обратиться к полюresult.detections
, но поскольку это поле не включено в результаты проекции, возникает ошибка.
Решение
Чтобы исправить данную ошибку, вам необходимо правильно настроить ваш запрос, чтобы включить массив result.detections
в проекцию перед тем, как применять операцию unwind
. Ниже приведен исправленный вариант кода:
ProjectionOperation projectionPreUnwind =
Aggregation.project(Fields.from(
Fields.field("result.detections"), // Включаем весь массив detections
Fields.field("result.detections.reference.control", "result.detections.reference.control")
));
UnwindOperation unwindOpn = Aggregation.unwind("result.detections");
Aggregation aggregation = Aggregation.newAggregation(projectionPreUnwind, unwindOpn);
LOGGER.info(" aggregation {}", aggregation);
AggregationResults<String> detectionsDataAggr =
mongoTemplate.aggregate(aggregation, CASES_COLLECTION, String.class);
Шаги по исправлению
-
Обновите проекцию: Убедитесь, что поле, к которому вы обращаетесь в операции
unwind
, включено в проекцию. В вашем случае используйте:Fields.field("result.detections")
чтобы вернуть весь массив
detections
. -
Правильная структура: Если вы хотите получать только поля
control
внутри массивовdetections
, убедитесь, что в проекции запрашиваются необходимые поля. -
Тестирование: После внесения изменений протестируйте код снова, чтобы убедиться, что ошибка устранена и данные извлекаются как ожидалось.
Заключение
Ошибка, связанная с unwind
в MongoDB, может быть устранена путем правильного формирования проекции. Убедитесь, что все нужные данные доступны в контексте операции. После внесения данных изменений ваш код должен работать корректно. Следите за структурой ваших запросов к MongoDB, так как они могут влиять на логику и производительность ваших агрегаций.