我在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.
型
你知道怎么才能让它工作吗?谢啦,谢啦
1条答案
按热度按时间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'
的历史记录),而不进行任何操作。字符串
输入:
型
输出量:
型
mongoplayground的