MongoDB Spring — получить значение динамически

У меня есть следующие документы, каждый из которых находится в другой коллекции

ресурсы

{
  "_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();
0
0
97
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это сложно, даже я новичок в 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 // старое решение

Я использовал совокупную конвейерную линию с операторами размотки, поиска и проекта. Надеюсь, это поможет вам.

не должно быть агрегирования для суммирования всех назначенных запасов из всех документов резервов, которые используют актив?

Wrong 31.07.2019 10:55

вы можете использовать $sum в агрегации, если она соответствует вашим требованиям. Если вы не хотите объяснить свою проблему на каком-то примере.

Sachin Vishwakarma 31.07.2019 12:15

да, мой пример заключается в том, что у меня может быть более одного резерва, и, например, два резерва могут иметь один и тот же актив с разными назначенными запасами. Например, резерву 1 назначена 1 единица актива с идентификатором 12345, а резерву 2 присвоено 3 единицы актива с идентификатором 12345. Итак, теперь мне нужно знать результат суммы всех назначенных единиц минус результат запас, который будет 20 - 4

Wrong 01.08.2019 08:24

@Неправильно, я изменил свой ответ, пожалуйста, проверьте

Sachin Vishwakarma 01.08.2019 17:51

Другие вопросы по теме