使用欧洲日期格式排序阶段

时间:2017-05-31 12:39:25

标签: mongodb mongodb-query aggregation-framework

我有一个像这样结构的集合:

_id    name    date
1      Dave    15.02.2014
2      Dave    24.01.2014
3      Dave    20.01.2014
...

我需要为每个first汇总lastname日期,这样我就会得到类似的结果:

_id    name    First_Date  Last_Date
1      Dave    20.01.2014  15.02.2014
... 

我正在尝试以下查询,但它没有成功,fie

db.users.aggregate([
  {   "$sort": {
          "date": 1
  }},
  {   "$group":  {
          "_id": 1,
          "name": {"$first": "$name"},
          "First_Date": {"$first": "$date"},
          "Last_Date": {"$last": "$date"}
  }}
  ]

问题:如何使用mongo查询实现这一目标?

1 个答案:

答案 0 :(得分:1)

要做到如何形成数据,您需要将字符串重新排序为“lexical”或“yyyymmdd”格式以允许它进行排序:

db.users.aggregate([
  { "$group": {
    "_id": "$name",
    "first_date": {
      "$min": {
        "$concat": [
           { "$substrCP": [ "$date", 6, 4 ] },
           { "$substrCP": [ "$date", 3, 2 ] },
           { "$substrCP": [ "$date", 0, 2 ] }
         ]
      }
    },
    "last_date": {
      "$max": {
        "$concat": [
           { "$substrCP": [ "$date", 6, 4 ] },
           { "$substrCP": [ "$date", 3, 2 ] },
           { "$substrCP": [ "$date", 0, 2 ] }
         ]
      }
    }
  }}
])

注意到 根据您的MongoDB版本,现代版本为$substrCP,旧版本为$substr

您还希望"name"上的$group使用$min$max累加器作为值。

要按照您的确实应该修改日期,您可以运行以下内容:

let ops = [];

db.users.find({ "date": { "$type": 2 } }).forEach(doc => {
  let dt = new Date(
    `${doc.date.substr(6,4)}/${doc.date.substr(3,2)}/${doc.date.substr(0,2)}`
  );

  ops = [
    ...ops,
    {
      "updateOne": {
        "filter": { "_id": doc._id },
        "update": { "$set": { "date": dt } }
      }
    }
  ];

  if ( ops.length >= 500 ) {
    db.users.bulkWrite(ops);
    ops = [];
  }
});

if ( ops.length > 0 ) {
  db.users.bulkWrite(ops);
  ops = [];
}