【问题标题】:Select data from two MongoDB tables and update the results从两个 MongoDB 表中选择数据并更新结果
【发布时间】:2021-04-03 01:49:59
【问题描述】:

我们有以下问题

给出的是表格和字段

  • 优惠

    • OfferId
    • 状态
  • 文章

    • OfferId
    • 文章编号
    • 净价
    • 总价
    • 增值税

示例数据:

优惠收集

{
    "_id": "1",
    "State": "INITIAL",
    "_class": "com.example.dto.OfferData"
}
{
    "_id": "2",
    "State": "COMPLETED",
    "_class": "com.example.dto.OfferData"
}

文章集

{
    "_id": {
        "$oid": "a"
    },
    "Description": "asdf",
    "NetPrice": "100",
    "GrossPrice": "116",
    "VatRate": "16",
    "OfferId": "1",
    "_class": "com.example.dto.Article"
}
{
    "_id": {
        "$oid": "b"
    },
    "Description": "my description",
    "NetPrice": "100",
    "GrossPrice": "119",
    "VatRate": "19",
    "OfferId": "1",
    "_class": "com.example.dto.Article"
}
{
    "_id": {
        "$oid": "c"
    },
    "Description": "my description",
    "NetPrice": "100",
    "GrossPrice": "116",
    "VatRate": "16",
    "OfferId": "2",
    "_class": "com.example.dto.Article"
}

现在我们必须通过以下方式更新属于状态为“初始”的报价的所有文章:如果增值税等于 16,则必须将其更新为 19,并且必须根据现有的净价格重新计算总价格。

结果应为: _id = "a" 且增值税率 = 16 且 OfferId = 1(州 = 初始)的商品应有增值税率 = 19 和总价格 = 119。字段应为更新并保留在原始 MongoDB 集合中。

我们可以只用 mongo-shell 做到这一点吗?我们的版本是 3.6。

我们的尝试: 我们玩过 .aggregate、$lookup、$match 和 $project,但运气不佳。这是我们第一次使用 mongo-shell。

db.getCollection("Offers").aggregate([{
        $lookup:{
            from:"Articles",
            localField:"OfferId",
            foreignField:"OfferId",
            as:"selected-articles"
        }
    },
    {
        $match: { "state": { "$eq": "INITIAL" } }
    },
    {
        $project: { "articles": 1 }
    }
]).forEach(...?)

感谢您的建议,祝圣诞快乐。

【问题讨论】:

  • 您是要更新查询还是要进行聚合查询来产生这个结果?你能在你的问题中添加你的尝试吗?
  • 我稍微编辑了我的问题 - 我不知道更新和聚合查询之间有什么区别

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:
  • $match 你的State 条件
  • $lookupArticles 收藏
  • $map 迭代 selected-articles 数组的循环,如果 VatRate 为“16”,则使用 $cond 检查条件,然后更新为 19 并根据 NetPrice 在将 NetPrice 转换为整数之前使用 $multiply 重新计算 GrossPrice因为它是字符串类型,返回使用$mergeObjects 将对象与当前对象合并
db.getCollection("Offers").aggregate([
  { $match: { State: { $eq: "INITIAL" } } },
  {
    $lookup: {
      from: "Articles",
      localField: "_id",
      foreignField: "OfferId",
      as: "selected-articles"
    }
  },
  {
    $addFields: {
      "selected-articles": {
        $map: {
          input: "$selected-articles",
          in: {
            $mergeObjects: [
              "$$this",
              {
                $cond: [
                  { $eq: ["$$this.VatRate", "16"] },
                  {
                    VatRate: 19,
                    GrossPrice: {
                      $multiply: [{ $toInt: "$$this.NetPrice" }, 19]
                    }
                  },
                  {}
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Playground

【讨论】:

  • 感谢您的努力。查询运行没有错误,但它似乎对我们的数据没有任何作用:执行脚本后增值税率和总价格保持不变。
  • 你的意思是结果?您能否为这两个集合发布一些示例文档。
  • 我附上了一些示例数据。这些字段应更新并保留在原始 MongoDB 集合中。
  • 更新了答案并添加了游乐场链接。
  • 可能是你的mingodb版本低于4.0,$toInt只支持form 4.0版本,我不认为有任何其他好的选择可以将stirng转换为低于4.0 versoin的int,如果你改变你的数字价格和字段为集合中的整数,那么您不需要使用该运算符,或者您可以更新您的 mongodb 4.0 或更高版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 2011-09-12
  • 1970-01-01
相关资源
最近更新 更多