使用 mongo.code.create 构造 $add 的数组参数

Use of mongo.code.create to construct array argument to $add

我有 MongoDB 个文件,如下所示:

{"_id":{"$oid":"56d810f5c91e6779a38386b8"},
 "timestamp": {"$numberLong":"1457000674750"}}

我正在构建一个聚合管道,其中应包含以下 $project 段:

{"$project": 
    {"date": {"$add": ["new Date(3600000)", "$timestamp"]}}
}   

这在 MongoDB shell 中有效,但我无法在 rmongodb 中使用它。例如,当包含在我的管道中时,以下给出错误 10(BSON 无效):

mongo.bson.from.list(list(
"$project"= list("date"=list("$add"=list( mongo.code.create("new Date(3600000)"), "$timestamp")))
))

我很确定问题与代码有关 (new Date(3600000)) and/or 它包含在数组中,而数组又是 $add 的参数。我想我可以构建 "old way" 的 BSON 缓冲区,但我正在寻找的是如何使用 mongo.bson.from.list and/or mongo.bson.from.JSON 来做到这一点。

如前所述,需要使用 "JavaScript Code" 来表示注入的 BSON 日期,而是语言环境中 Date 的任何本机格式。

因此在 r 中,您可以使用以下构造函数来获取 Date 纪元:

as.POSIXct("1970-01-01",tz="GMT")

所以在对数值进行 BSON 日期转换并从中提取 $year 的示例中:

pipeline <- list(
  mongo.bson.from.list(list(
    '$project' = list(
      'test' =  list( '$year' = 
        list( '$add' = list (
          '$timestamp',
          as.POSIXct("1970-01-01",tz="GMT"),
          3600000
        ))
      )
    )
  ))
)

也就是说,没有什么能阻止您将基本数学直接应用于数值,就像序列化符号的运算符示例一样:

{ "$project": {
    "test": {
        "$add": [
            { "$divide": [
                { "$subtract": [
                    { "$add": [ "$timestamp",3600000 ] },
                    { "$mod": [ 
                        { "$add": [ "$timestamp", 3600000 ] }, 
                        1000 * 60 * 60 * 24 * 365
                    ]}
                ]},
                1000 * 60 * 60 * 24 * 365
            ]},
            1970
        ]
    }
}}

也计算出当前的 "year",同样的操作可以应用于日期的任何部分,无论是 "dayOfYear" 的当前 "year" 还是任何东西。

另请注意,如果您打算 $group,并不真正推荐使用 $project,因为您最好直接将 "conversions" 用于分组 _id而不是在单独的管道阶段,出于性能原因避免另一个管道传递。

真正需要 $addDate 的唯一一次是在转换后的 "millisecond from epoch" 的最终输出中"output" 中您想要 BSON 日期而不是数值的值。