Mongodb -从同一数组元素中的另一个属性更新数组中的属性

9rygscc1  于 2023-08-04  发布在  Go
关注(0)|答案(1)|浏览(106)

我在MongoDB中有以下集合:

{
  "_id":"123456",
  "history":[
     {
        "date": 1674926893449,
        "name": "Hello"
     },
     {
        "date": 1631548766655,
        "name": "Super"
     }
  ]
}

字符串
属性history.date当前是unix时间戳,但我正在重新构造对象,并希望使用Mongo操作符$toDate获得Date类型的属性。我需要做一个查询,它将获取date属性并在同一个数组元素中创建一个属性dateTime,如下所示:

{
  "_id":"123456",
  "history":[
     {
        "date": 1674926893449,
        "name": "Hello",
        "dateTime": 2023-01-28T17:28:13.449+00:00
     },
     {
        "date": 1631548766655,
        "name": "Super",
        "dateTime": 2021-09-13T15:59:26.655+00:00
     }
  ]
}


date属性可能为0,因此在这种情况下,属性dateTime应该具有null值。
最后我写了这个问题,但我错过了一些东西:

db.invoice.updateMany({"history.dateTime":{$exists:false}}, {$set : { "history.$[elem].dateTime" : { $cond: { if: { $gt: [ "history.$[elem].$date", 0 ] }, then: { $toDate: "history.$[elem].$date" }, else: null }}}}, { "arrayFilters": [{ "elem.dateTime": {$exists:false} }] })


在这种情况下,Mongo返回错误:

The dollar ($) prefixed field '$cond' in 'history.0.dateTime.$cond' is not valid for storage.


你知道怎么才能让它工作吗?谢啦,谢啦

z9gpfhce

z9gpfhce1#

我们可以使用聚合管道状态:$addFields。我们使用$match stage和$elemMatch来过滤不存在history.dateTime的文档。带有_id: 2的文档将被过滤。
$addFields阶段,我们使用$map将表达式应用于数组中的每一项,并返回一个包含应用结果的数组。
如果history.date大于0,并且history.dateTime字段不存在,则创建一个dateTime字段,其值是history.date通过$toDate转换的值,然后使用$mergeObjects将当前历史($$h)与{ dateTime: <ISO Date> }对象组合。
否则,返回当前的历史记录(带有name: 'c'的历史记录),而不进行任何操作。

db.collection.aggregate([
  {
    "$match": {
      history: {
        $elemMatch: {
          dateTime: {
            $exists: false
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "history": {
        $map: {
          input: "$history",
          as: "h",
          in: {
            $cond: {
              if: {
                $and: [
                  {
                    $gt: [
                      "$$h.date",
                      0
                    ]
                  },
                  {
                    "$eq": [
                      {
                        $ifNull: [
                          "$$h.dateTime",
                          true
                        ]
                      },
                      true
                    ]
                  }
                ]
              },
              then: {
                $mergeObjects: [
                  "$$h",
                  {
                    "dateTime": {
                      $toDate: "$$h.date"
                    }
                  }
                ]
              },
              else: "$$h"
            }
          }
        }
      }
    }
  }
])

字符串
输入:

[
  {
    "_id": "1",
    "history": [
      {
        "date": 1674926893449,
        "name": "Hello"
      },
      {
        "date": 1631548766655,
        "name": "Super"
      },
      {
        "date": 1631548766655,
        "name": "c",
        "dateTime": "2022-01-01"
      }
    ]
  },
  {
    "_id": "2",
    "history": [
      {
        "date": 1674926893449,
        "name": "a",
        "dateTime": null
      },
      {
        "date": 1631548766655,
        "name": "b",
        "dateTime": null
      }
    ]
  }
]


输出量:

[
  {
    "_id": "1",
    "history": [
      {
        "date": 1.674926893449e+12,
        "dateTime": ISODate("2023-01-28T17:28:13.449Z"),
        "name": "Hello"
      },
      {
        "date": 1.631548766655e+12,
        "dateTime": ISODate("2021-09-13T15:59:26.655Z"),
        "name": "Super"
      },
      {
        "date": 1.631548766655e+12,
        "dateTime": "2022-01-01",
        "name": "c"
      }
    ]
  }
]


mongoplayground

相关问题