【问题标题】:MongoDB multiply values inside two arraysMongoDB将两个数组内的值相乘
【发布时间】:2019-02-15 21:25:18
【问题描述】:

我需要帮助将对象数组中的值相乘以获得输出。

这是我的 JSON

/* 1 */
{
    "_id" : ObjectId("5b919a785cb288f7d5311846"),
    "nome" : "Antonio",
    "cod_produtor" : "PR001",
    "morada" : {
        "rua" : "Rua dos Carvalhos",
        "n_porta" : 12.0,
        "cod_postal" : "4567-123"
    },
    "data-registo" : ISODate("2017-07-22T03:41:20.201+0000"),
    "colheita" : {
        "cod_colheita" : "COL001",
        "ano" : 2018.0,
        "tipo_maça" : "Ambrosia",
        "precario" : [ 
            {
                "valor" : "0-60",
                "preço" : 0.1
            }, 
            {
                "valor" : "60-65",
                "preço" : 0.12
            }, 
            {
                "valor" : "65-70",
                "preço" : 0.15
            }, 
            {
                "valor" : "70-75",
                "preço" : 0.17
            }, 
            {
                "valor" : "75-80",
                "preço" : 0.2
            }, 
            {
                "valor" : "80+",
                "preço" : 0.23
            }, 
            {
                "valor" : "85-90",
                "preço" : 0.25
            }, 
            {
                "valor" : "90+",
                "preço" : 0.3
            }, 
            {
                "valor" : "DEFEITO",
                "preço" : 0.05
            }
        ],
        "Lote" : {
            "Número Lote" : "FE9450H",
            "Peso" : 4495.0,
            "calibragem" : [ 
                {
                    "valor" : "0-60",
                    "quantidade" : 22.0
                }, 
                {
                    "valor" : "60-65",
                    "quantidade" : 224.0
                }, 
                {
                    "valor" : "65-70",
                    "quantidade" : 624.0
                }, 
                {
                    "valor" : "70-75",
                    "quantidade" : 1183.0
                }, 
                {
                    "valor" : "75-80",
                    "quantidade" : 1424.0
                }, 
                {
                    "valor" : "80+",
                    "quantidade" : 911.0
                }, 
                {
                    "valor" : "85-90",
                    "quantidade" : 45.0
                }, 
                {
                    "valor" : "90+",
                    "quantidade" : 6.0
                }, 
                {
                    "valor" : "DEFEITO",
                    "quantidade" : 54.0
                }
            ],
            "TOTAL" : 4493.0,
            "DIFERENÇA" : -2.0
        }
    }
}

/* 2 */
{
    "_id" : ObjectId("5b91a8f65cb288f7d5311b50"),
    "nome" : "João",
    "cod_produtor" : "PR002",
    "morada" : {
        "rua" : "Rua dos Travessas",
        "n_porta" : 169.0,
        "cod_postal" : "9871-456"
    },
    "data-registo" : ISODate("2016-12-24T08:43:20.201+0000"),
    "colheita" : {
        "cod_colheita" : "COL005",
        "ano" : 2018.0,
        "tipo_maça" : "Golden",
        "precario" : [ 
            {
                "valor" : "0-60",
                "preço" : 0.1
            }, 
            {
                "valor" : "60-65",
                "preço" : 0.12
            }, 
            {
                "valor" : "65-70",
                "preço" : 0.15
            }, 
            {
                "valor" : "70-75",
                "preço" : 0.17
            }, 
            {
                "valor" : "75-80",
                "preço" : 0.2
            }, 
            {
                "valor" : "80+",
                "preço" : 0.23
            }, 
            {
                "valor" : "85-90",
                "preço" : 0.25
            }, 
            {
                "valor" : "90+",
                "preço" : 0.3
            }, 
            {
                "valor" : "DEFEITO",
                "preço" : 0.05
            }
        ],
        "Lote" : {
            "Número Lote" : "FE1283961",
            "Peso" : 1234.0,
            "calibragem" : [ 
                {
                    "valor" : "0-60",
                    "quantidade" : 22.0
                }, 
                {
                    "valor" : "60-65",
                    "quantidade" : 101.0
                }, 
                {
                    "valor" : "65-70",
                    "quantidade" : 223.0
                }, 
                {
                    "valor" : "70-75",
                    "quantidade" : 183.0
                }, 
                {
                    "valor" : "75-80",
                    "quantidade" : 424.0
                }, 
                {
                    "valor" : "80+",
                    "quantidade" : 11.0
                }, 
                {
                    "valor" : "85-90",
                    "quantidade" : 5.0
                }, 
                {
                    "valor" : "90+",
                    "quantidade" : 6.0
                }, 
                {
                    "valor" : "DEFEITO",
                    "quantidade" : 54.0
                }
            ],
            "TOTAL" : 1029.0,
            "DIFERENÇA" : 205.0
        }
    }
}

/* 3 */
{
    "_id" : ObjectId("5b91a9855cb288f7d5311b72"),
    "nome" : "Antonio",
    "cod_produtor" : "PR001",
    "morada" : {
        "rua" : "Rua dos Carvalhos",
        "n_porta" : 12.0,
        "cod_postal" : "4567-123"
    },
    "data-registo" : ISODate("2017-07-22T03:41:20.201+0000"),
    "colheita" : {
        "cod_colheita" : "COL001",
        "ano" : 2017.0,
        "tipo_maça" : "Ambrosia",
        "precario" : [ 
            {
                "valor" : "0-60",
                "preço" : 0.1
            }, 
            {
                "valor" : "60-65",
                "preço" : 0.12
            }, 
            {
                "valor" : "65-70",
                "preço" : 0.15
            }, 
            {
                "valor" : "70-75",
                "preço" : 0.17
            }, 
            {
                "valor" : "75-80",
                "preço" : 0.2
            }, 
            {
                "valor" : "80+",
                "preço" : 0.23
            }, 
            {
                "valor" : "85-90",
                "preço" : 0.25
            }, 
            {
                "valor" : "90+",
                "preço" : 0.3
            }, 
            {
                "valor" : "DEFEITO",
                "preço" : 0.05
            }
        ],
        "Lote" : {
            "Número Lote" : "FE9450H",
            "Peso" : 1000.0,
            "calibragem" : [ 
                {
                    "valor" : "0-60",
                    "quantidade" : 50.0
                }, 
                {
                    "valor" : "60-65",
                    "quantidade" : 150.0
                }, 
                {
                    "valor" : "65-70",
                    "quantidade" : 200.0
                }, 
                {
                    "valor" : "70-75",
                    "quantidade" : 250.0
                }, 
                {
                    "valor" : "75-80",
                    "quantidade" : 150.0
                }, 
                {
                    "valor" : "80+",
                    "quantidade" : 100.0
                }, 
                {
                    "valor" : "85-90",
                    "quantidade" : 45.0
                }, 
                {
                    "valor" : "90+",
                    "quantidade" : 15.0
                }, 
                {
                    "valor" : "DEFEITO",
                    "quantidade" : 40.0
                }
            ],
            "TOTAL" : 1000.0,
            "DIFERENÇA" : 0.0
        }
    }
}

/* 4 */
{
    "_id" : ObjectId("5b91ab8c5cb288f7d5311bed"),
    "nome" : "Antonio",
    "cod_produtor" : "PR001",
    "morada" : {
        "rua" : "Rua dos Carvalhos",
        "n_porta" : 12.0,
        "cod_postal" : "4567-123"
    },
    "data-registo" : ISODate("2017-07-22T03:41:20.201+0000"),
    "colheita" : {
        "cod_colheita" : "COL001",
        "ano" : 2017.0,
        "tipo_maça" : "Ambrosia",
        "precario" : [ 
            {
                "valor" : "0-60",
                "preço" : 0.1
            }, 
            {
                "valor" : "60-65",
                "preço" : 0.12
            }, 
            {
                "valor" : "65-70",
                "preço" : 0.15
            }, 
            {
                "valor" : "70-75",
                "preço" : 0.17
            }, 
            {
                "valor" : "75-80",
                "preço" : 0.2
            }, 
            {
                "valor" : "80+",
                "preço" : 0.23
            }, 
            {
                "valor" : "85-90",
                "preço" : 0.25
            }, 
            {
                "valor" : "90+",
                "preço" : 0.3
            }, 
            {
                "valor" : "DEFEITO",
                "preço" : 0.05
            }
        ],
        "Lote" : {
            "Número Lote" : "FE9450H",
            "calibragem" : [ 
                {
                    "valor" : "0-60",
                    "quantidade" : 50.0
                }, 
                {
                    "valor" : "60-65",
                    "quantidade" : 150.0
                }, 
                {
                    "valor" : "65-70",
                    "quantidade" : 200.0
                }, 
                {
                    "valor" : "70-75",
                    "quantidade" : 250.0
                }, 
                {
                    "valor" : "75-80",
                    "quantidade" : 150.0
                }, 
                {
                    "valor" : "80+",
                    "quantidade" : 100.0
                }, 
                {
                    "valor" : "85-90",
                    "quantidade" : 45.0
                }, 
                {
                    "valor" : "90+",
                    "quantidade" : 15.0
                }, 
                {
                    "valor" : "DEFEITO",
                    "quantidade" : 40.0
                }
            ],
            "TOTAL" : 1000.0,
            "DIFERENÇA" : 0.0
        }
    }
}

我需要做的是将值colheita.precariocolheita.Lote.calibragem 相乘以获得它们的总和。在colheita.precario 内部有valorpreço,在colheita.Lote.calibragem 内部有valorquantidade。字段valor 必须匹配然后乘以preço * quantidade

其实我有两种不同的方法。但他们都没有工作。 我在想这样的事情:

使用 STUDIO 3T

第 1 阶段 - 比赛

这里我需要匹配不同的东西

{
    "cod_produtor" : "PR001", 
    "colheita.ano" : 2017
}

第 2 阶段 - 项目

{
    // specifications
    _id : "$colheita.Lote.Número Lote",
    total: {
        $sum:[
            { 
                "$multiply": [
                    "$colheita.precario.0.preço", 
                    "$colheita.Lote.0.quantidade"
                ] 
            },
            { 
                "$multiply" : [
                    "$colheita.precario.1.preço", 
                    "$colheita.Lote.1.quantidade"
                ] 
            }
        ]
   }
}

但这不起作用,因为它给出了一个错误:

$sum 累加器是一元运算符”

非常感谢您的帮助

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以在 3.4 聚合中使用以下项目。

    $range 迭代 colheita.precario inside$map 并输出包含数组字段与 preco 和 quantidade 相乘的值。

    $let 带有索引的表达式(来自 $range (ix) )输出 colheita.precario 和 Lote.calibragem 元素。

    $project$sum 输出数组值的总和。

    {
      "$project":{"total":{
        "$sum":{
          "$map":{
            "input":{"$range":[0,{"$size":"$colheita.precario"}]},
            "as":"ix",
            "in":{
              "$let":{
                "vars":{
                  "pre":{"$arrayElemAt":["$colheita.precario","$$ix"]},
                  "cal":{"$arrayElemAt":["$colheita.Lote.calibragem","$$ix"]}
                },
                "in":{"$multiply":["$$pre.preço","$$cal.quantidade"]}
              }
            }
          }
        }
      }}
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用下面的聚合

      db.state.aggregate(
      
      // Pipeline
      [
          // Stage 1
          {
              $unwind: {
                  path : "$colheita.precario",
                  includeArrayIndex : "arrayIndex", // optional
                  preserveNullAndEmptyArrays : false // optional
              }
          },
      
          // Stage 2
          {
              $unwind: {
                  path : "$colheita.Lote.calibragem",
                  includeArrayIndex : "arrayIndex", // optional
                  preserveNullAndEmptyArrays : false // optional
              }
          },
      
          // Stage 3
          {
              $project: {
                   "total": {
                          "$cond": { 
                              "if": { "$eq": [ "$colheita.precario.valor", "$colheita.Lote.calibragem.valor" ] }, 
                              "then": { $multiply: [ "$colheita.precario.preço", "$colheita.Lote.calibragem.quantidade" ] },
                              "else": 0
                          }
                   }
              }
          },
      
          // Stage 4
          {
              $group: {
                  "_id":"$_id",
                  totalAmount: { $sum: "$total" }
              }
          },
      ]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-24
        • 1970-01-01
        • 2013-09-21
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多