仅当内部对象具有不同值时才创建新数组元素

Create new array element only if inner object has different value

{
  FullName: "Emily Clark",
  Details: {
    Income: [
      {
        2021: [
          {
            time: "Sun Apr 11 2021 17:42:39 GMT+0530 (India Standard Time)",
            description: "Web",
            amount: "3700",
          },
          {
            time: "Sun May 21 2022 07:12:59 GMT+0530 (India Standard Time)",
            description: "Pc Monitor",
            amount: "45000",
          },
        ],
      },
      {
        2022: [
          {
            time: "Sat May 28 2022 12:23:34 GMT+0530 (India Standard Time)",
            description: "Class",
            amount: "4100",
          },
        ],
      },
    ],
    Expense: [
      {
        2022: [
          {
            time: "Tue May 17 2022 20:30:39 GMT+0530 (India Standard Time)",
            descritption: "Car Wash",
            amount: 4000,
          },
          {
            time: "Fri May 19 2022 10:23:29 GMT+0530 (India Standard Time)",
            description: "Loundry",
            amount: "300",
          },
        ],
      },
    ],
  },
};

在这里,我首先向 Details.Income.0.2021 添加了一个新的支出数据对象,因此它在收入之后创建了一个新的数组和对象,但是在为新的 2022 年添加了新的支出数据之后,它被添加到现有的第一个收入元素的对象,如果年份不存在,如何为新年创建一个新的数组对象?

第二个 Income 元素是我从 MongoDB shell.

手动添加的

如果年份存在,我希望数据看起来像 Expense,其中它有两个对象数据,都是同一年。

我知道这个解释有点乱,但如果需要我愿意提供更多信息。

编辑: 由于 IncomeExpense 是对象数组,其中每个年份都是一个键,因此所有解决方案都比较复杂。

一种选择是执行如下操作:

  1. 将新项目添加到文档中,
  2. Income
  3. 上计算 lastYear
  4. 如果 lastYear 与输入的年份 yearString 不同,则添加新的年份
  5. Details.Income 中删除最后一年以便对其进行编辑。保持为 last.
  6. 向其中添加新项目。
  7. 将其合并回原来的结构。
db.collection.update({
  FullName: "Emily Clark"
},
[
  {$addFields: {
      newItem: {a: "test"},
      year: yearString
    }
  },
  {
    $addFields: {
      lastYear: {
        $reduce: {
          input: {$objectToArray: {$last: "$Details.Income"}},
          initialValue: "",
          in: {$concat: ["$$value", "$$this.k"]}
        }
      }
    }
  },
  {
    $addFields: {
      newArr: {
        $cond: [
          {$eq: ["$lastYear", "$year"]},
          [],
          [{yearString: []}]
        ]
      }
    }
  },
  {
    $set: {
      "Details.Income": {
        $concatArrays: ["$Details.Income", "$newArr"]
      },
      year: "$$REMOVE",
      newArr: "$$REMOVE"
    }
  },
  {
    $set: {
      last: {$objectToArray: {$last: "$Details.Income"}},
      "Details.Income": {
        $slice: ["$Details.Income", {$subtract: [{$size: "$Details.Income"}, 1]
          }
        ]
      }
    }
  },
  {
    $set: {
      last: {
        $map: {
          input: "$last",
          as: "item",
          in: {
            v: {$concatArrays: ["$$item.v", ["$newItem"]]},
            k: "$$item.k"
          }
        }
      }
    }
  },
  {$set: {last: {$arrayToObject: ["$last"]}}},
  {
    $set: {
      "Details.Income": {$concatArrays: ["$Details.Income", ["$last"]]},
      last: "$$REMOVE",
      newItem: "$$REMOVE",
      lastYear: "$$REMOVE"
    }
  }
])

Playground example

如果 IncomeExpense 是一个对象而不是对象数组,它会很简单:

db.collection.update({
  FullName: "Emily Clark"
},
{
  $push: {
    "Details.Expense.2022": 
     {
        time: "Fri May 19 2022 10:23:29 GMT+0530 (India Standard Time)",
        description: "Loundry",
        amount: "300",
      }
  }
})