2017-05-31 63 views
0

我有结构化的这样一个集合:排序阶段

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

我需要聚集firstlast日期每name,这样我结束了这样的事情:

_id name First_Date Last_Date 
1  Dave 20.01.2014 15.02.2014 
... 

我试图下面的查询,但没有工作顺利,外商投资企业

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

问题:mongo查询如何实现?

+0

你真正的意思是,“日期”实际上是“字符串”吧?所以,“真正”应该发生在这里的是,通过将它们解析为适当的BSON'Date'对象来修复日期。除了有用之外,还可以正确排序和正确过滤范围,存储大小也远远小于当前字符串的长度。 –

+0

如果你认为你需要一个“欧洲格式”字符串,那么这是不正确的。 BSON日期的全部内容就是它可以直接用你选择的编程语言作为自然日期类型。所有这些都将有广泛的选项来格式化给定语言环境的日期。使用'Date'类型。不是字符串。您可以“强制”一些东西来解决您在这里问的问题,但您可以通过简单地使用正确的存储类型“轻松”完成。 –

+0

@NeilLunn我看着它。通过'mongoimport'从csv导入这些数据。 – ffritz

回答

1

要做到这一点的数据是如何目前形成,则需要重新排序的字符串为“词汇”或`“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",并使用$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 = []; 
} 
+1

从现在起,这教会了我使用BSON日期格式。非常感谢! – ffritz