У меня есть следующие документы, каждый из которых находится в другой коллекции
ресурсы
{
"_id": "1234",
"name": "Needle",
"initialStock": 20
},
{
"_id": "12345",
"name": "Serum",
"initialStock": 5
}
резервы
{
"_id: "12345,
"from" : ISODate("2019-07-30T07:09:00.000Z"),
"to" : ISODate("2019-08-30T11:00:00.000Z"),
"assets": [
{
"_id": "1234",
"assignedStock": 10
},
"_id": "12345",
"assignedStock": 1
}
]
}
Как я могу получить вычитание assignedStock и initialStock между двумя заданными датами? Например, «Я хочу узнать доступный запас этого актива между двумя датами (от и до)».
Как это можно сделать на Spring? (простой Монго тоже дал бы мне подсказку).
Мой текущий код выглядит следующим образом, но я просто получаю пустой массив в активах:
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("assets")
.localField("assets._id")
.foreignField("_id")
.as("assets");
Criteria criteria = Criteria.where("from")
.gte(from)
.and("to")
.lte(to)
.and("assets")
.not().size(0)
.elemMatch(
Criteria.where("_id")
.is(idAsset)
);
Aggregation aggregation = Aggregation.newAggregation(match(criteria), lookupOperation);
List<Document> results =
this.mongoTemplate.aggregate(aggregation, "reserved", Document.class).getMappedResults();
Это сложно, даже я новичок в MongoDB и считаю этот запрос сложным. Однако мне удалось написать запрос, который возвращает вам желаемый результат. Я использовал mongo playgroud для имитации сценария, который вы указали в вопросе.
db.reserves.aggregate([
{
$unwind: {
path: "$assets"
}
},
{
$group: {
_id: "$assets._id",
sumAssigned: {
$sum: "$assets.assignedStock"
},
}
},
{
$lookup: {
from: "assets",
localField: "_id",
foreignField: "_id",
as: "asset_lookup"
}
},
{
$project: {
sumAssigned: 1,
initialStock: {
$sum: "$asset_lookup.initialStock"
},
availableStock: {
$subtract: [
"$sumAssigned",
{
$sum: "$asset_lookup.initialStock"
}
]
}
}
}
])https://mongoplayground.net/p/h5eMWIE5q4p // новое решение
https://mongoplayground.net/p/r1bcoUjD3eG // старое решение
Я использовал совокупную конвейерную линию с операторами размотки, поиска и проекта. Надеюсь, это поможет вам.
вы можете использовать $sum в агрегации, если она соответствует вашим требованиям. Если вы не хотите объяснить свою проблему на каком-то примере.
да, мой пример заключается в том, что у меня может быть более одного резерва, и, например, два резерва могут иметь один и тот же актив с разными назначенными запасами. Например, резерву 1 назначена 1 единица актива с идентификатором 12345, а резерву 2 присвоено 3 единицы актива с идентификатором 12345. Итак, теперь мне нужно знать результат суммы всех назначенных единиц минус результат запас, который будет 20 - 4
@Неправильно, я изменил свой ответ, пожалуйста, проверьте
не должно быть агрегирования для суммирования всех назначенных запасов из всех документов резервов, которые используют актив?