首页 > 解决方案 > 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 上做到这一点?(普通的 Mongo 也会给我一个线索)。

我当前的代码如下,但我只是在资产中得到一个空数组:

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();

标签: springmongodbspring-bootlookupaggregation

解决方案


这很棘手,即使我是 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 // 旧解决方案

我使用了带有展开、查找和项目操作符的聚合管道。希望它可以帮助你。


推荐阅读