MongoDB添加从datetime计算并转换为整数的新字段

MongoDB添加从datetime计算并转换为整数的新字段,mongodb,datetime,type-conversion,integer,aggregation-framework,Mongodb,Datetime,Type Conversion,Integer,Aggregation Framework,I'va是MongoDB v3.2.12上的MongoDB集合,拥有约10亿条记录。 集合有一个datetime键。我需要向集合中添加一个新键,该键派生自datetime键,例如值为yyyymmdd,并将其另存为整数 现在,使用下面的命令,我能够创建一个以新键作为字符串的重复集合 db.log.aggregate( [ { "$addFields": { "date_ref": { $dateToString: { format: "%Y%m%d

I'va是MongoDB v3.2.12上的MongoDB集合,拥有约10亿条记录。 集合有一个datetime键。我需要向集合中添加一个新键,该键派生自datetime键,例如值为yyyymmdd,并将其另存为整数

现在,使用下面的命令,我能够创建一个以新键作为字符串的重复集合

db.log.aggregate(
    [
        { "$addFields": { 
            "date_ref": { $dateToString: { format: "%Y%m%d", date: "$log_date" } } 
        }},
        { "$out": "log_test" }
    ]
)
尝试按以下方式添加NumberPrint或parseInt无效

db.log.aggregate(
    [
        { "$addFields": { 
            "date_ref": NumberInt( { $dateToString: { format: "%Y%m%d", date: "$log_date" } } )
        }},
        { "$out": "log_test" }
    ]
)
使用numberprint,我将所有值都设置为0。 使用parseInt,我将所有值都设置为“NAN”

我知道我可以使用一个新键和一个foreach语句,如下所示:

db.log_test.find().forEach( function (l) {
  l.date_ref_int = parseInt(l.date_ref); 
  db.log_test.save(l);
});
但这种方法在时间上非常昂贵。 那么,是否可以在聚合中进行转换

更新

我尝试的另一种方法是:

db.log.aggregate(
    [
        { "$addFields": { 
            "date_ref_string": { $dateToString: { format: "%Y%m%d", date: "$log_date" } },
            "date_ref": NumberInt("date_ref_string") 
        }},
        { "$out": "log_test" }
    ]
)
我没有收到任何错误,但日期\u ref始终为0

更新2

根据@Veeram的建议,我制作了这个脚本:

db.log.aggregate(
    [
        { $addFields: 
            { "date_ref": 
                { $divide:
                    [
                        { $add:
                            [
                                { $multiply: [{"$year" : "$log_date"}, 10000000]}, 
                                { $multiply: [{"$month" : "$log_date"}, 100000]}, 
                                { $multiply: [{"$dayOfMonth" : "$log_date"}, 1000]}
                            ]
                        }, 1000
                    ]
                }
            }
        },
        { "$out": "log_test" }
    ]
);

这是可行的,但我得到的值是双倍的。我更喜欢整数,因为我需要在新计算的键上建立一个索引,如果该键是整数类型,它会更小。

您可以使用下面的聚合查询

db.log.aggregate([
  {"$addFields":{
    "date_ref":{
      "$trunc":{
        "$divide":[
          {"$add":[
            {"$multiply":[{"$year":"$log_date"},10000000]},
            {"$multiply":[{"$month":"$log_date"},100000]},
            {"$multiply":[{"$dayOfMonth":"$log_date"},1000]}
          ]},
          1000
        ]
      }
    }
  }}
])

你的mongodb版本是什么?您只需要将日期部分转换为毫秒吗?MongoDB v3.2.12在生产中,但在我的本地测试机上是3.6。我不需要毫秒,但需要来自yyyymmdd的整数值,例如20180125。对不起,您无法更改聚合管道@Veeram中的类型。请查看我的问题更新,并告诉我是否可以使用该类型?不,聚合框架中支持字符串到整数的转换。复制/粘贴,但它会给我以下错误:2018-01-30T09:35:13.917+0100 E QUERY[thread1][src/mongo/shell/utils.js:25:13]错误:命令失败:{ok:0,errmsg:Invalid$addFields::cause by::FieldPath字段名称不能以“$”开头,代码:16410,代码名:Location16410}:聚合失败。是否可以尝试db.log\u test.find{date\u ref:{$type:16}?你在看贝壳吗?我在和机器人3T v1.1合作。相反,该脚本在MongoDB shell上执行,由.js文件加载。通过对集合执行命令,我返回0条记录。Nevermind$trunc仅保留整数部分,但仍将值保留为dobule值。对不起,看起来不可能……哦。。。所以不是我想要的。我需要的类型是整数,以减少新键上的索引大小,并有更好的性能,因为记录是10亿以上。