Mongo 凌乱的 DOB 字符串字段到年龄

Mongo messy DOB string field to Age

我有一个包含以下文件的集合:

{'state': 'NY', 'DOB': '2000-01-02'},
{'state': 'NY', 'DOB': '2002/03/04'},
{'state': 'NY', 'DOB': '00-00-00'},
{'state': 'NY', 'DOB': 'male'},
...

我想要这样的输出:

{'state': 'NY', 'DOB': '2000-01-02', 'Age': 21},
{'state': 'NY', 'DOB': '2002/03/04', 'Age': 19},
{'state': 'NY', 'DOB': '00-00-00', 'Age': None}, # or Mongo None equivalent
{'state': 'NY', 'DOB': 'male', 'Age': None}, # or Mongo None equivalent
...

我正在 PyMongo 中构造聚合查询,我想知道是否有一种聚合方法可以尝试将字段转换为 Mongo 日期对象,然后提取 Age,否则(如果无法提取日期),return None。 shell下面的某些条件?

def map_age(state, city)
    db.aggregate([
        {'$match': {
             'state': state,
             'DOB': {"$exists": True}, 
             'Age': {"$exists": False}
        }},
        {...}     
    ])

根据@prasad_ 的建议,您必须在 $project$addFields 阶段使用 $dateFromString 运算符。

db.collection.aggregate([
  {
    "$project": {
      "age": {
        "$dateFromString": {
          dateString: "$DOB",
          onError: null,
          onNull: null,
        }
      }
    }
  }
])

你可以试试,

  • $let为dob转换创建变量并做操作
  • $dateFromString 将字符串转换为日期,如果有效则替换为“None”
  • $subtract 从当前日期减去转换后的日期 $$NOW 你也可以使用 new Date()
  • $divide上面的日期减去“31536000000”表示“3652460601000”
  • $round 四舍五入年龄数字
db.aggregate([
  {
    $set: {
      Age: {
        $let: {
          vars: {
            dob: {
              $dateFromString: {
                dateString: "$DOB",
                onError: "None"
              }
            }
          },
          in: {
            $cond: [
              { $eq: ["$$dob", "None"] },
              "None",
              {
                $round: {
                  $divide: [
                    { $subtract: ["$$NOW", "$$dob"] },
                    31536000000 // 365*24*60*60*1000
                  ]
                }
              }
            ]
          }
        }
      }
    }
  }
])

Playground