MongoDB 3.4.19中$dateToString返回[object Object]及自定义日期格式拼接字段问题求助
解决MongoDB 3.4中给文档添加指定格式日期拼接字段的问题
你遇到的问题很典型:$dateToString是MongoDB聚合框架的专属操作符,没法直接在客户端的forEach JavaScript函数里直接调用,所以才会出现[object Object]的异常结果;而直接拼接doc.created时,本质是把JavaScript的Date对象转成默认字符串,自然会带出时区后缀。下面针对MongoDB 3.4.19版本,给你两种实用的解决方案:
方案一:客户端JavaScript手动格式化日期
从数据库查询出来的doc.created是标准的JavaScript Date对象,我们可以用它的原生方法手动拼接成你需要的格式:
1. 生成YYYY-MM-DD HH-MM格式(和你最初期望的$dateToString格式一致)
db.test.find({}).forEach(function(doc) { // 处理日期各部分,注意月份从0开始,要加1补全 const year = doc.created.getFullYear(); const month = String(doc.created.getMonth() + 1).padStart(2, '0'); const day = String(doc.created.getDate()).padStart(2, '0'); const hours = String(doc.created.getHours()).padStart(2, '0'); const minutes = String(doc.created.getMinutes()).padStart(2, '0'); const formattedDate = `${year}-${month}-${day} ${hours}-${minutes}`; doc.externalId = `${doc.name}_${formattedDate}`; db.test.save(doc); });
2. 生成类似ISODate的2021-07-12T08:22:16.688格式
直接利用Date对象的toISOString()方法,再截取到毫秒部分即可:
db.test.find({}).forEach(function(doc) { // toISOString()返回完整带时区的字符串,截取前23位得到目标格式 const formattedDate = doc.created.toISOString().slice(0, 23); doc.externalId = `${doc.name}_${formattedDate}`; db.test.save(doc); });
3. 生成去掉时区后缀的Sun Sep 12 2021 11:22:16格式
通过正则匹配并移除时区后缀:
db.test.find({}).forEach(function(doc) { // 匹配GMT开头的时区部分并替换为空 const formattedDate = doc.created.toString().replace(/ GMT.*$/, ''); doc.externalId = `${doc.name}_${formattedDate}`; db.test.save(doc); });
方案二:使用服务器端聚合管道更新(更高效)
MongoDB 3.4开始支持在updateMany中使用聚合管道,无需把所有文档拉到客户端处理,直接在服务器端完成操作,适合大集合场景:
1. 生成YYYY-MM-DD HH-MM格式
db.test.updateMany( {}, // 匹配所有文档 [ { $set: { externalId: { $concat: [ "$name", "_", { $dateToString: { format: "%Y-%m-%d %H-%M", date: "$created" } } ] } } } ] );
2. 生成类似ISODate的2021-07-12T08:22:16.688格式
通过$dateToString的自定义格式符实现:
db.test.updateMany( {}, [ { $set: { externalId: { $concat: [ "$name", "_", { $dateToString: { format: "%Y-%m-%dT%H:%M:%S.%L", date: "$created" } } ] } } } ] );
小提示
- 方案二更适合数据量较大的集合,能大幅减少客户端与服务器之间的数据传输开销
$dateToString的格式符可参考:%Y(4位年份)、%m(2位月份)、%d(2位日期)、%H(24小时制小时)、%M(分钟)、%S(秒)、%L(毫秒)
内容的提问来源于stack exchange,提问作者RanAB
相关产品推荐
相关产品推荐

