我有一个像这样结构的集合:
_id name date
1 Dave 15.02.2014
2 Dave 24.01.2014
3 Dave 20.01.2014
...
我需要为每个first
汇总last
和name
日期,这样我就会得到类似的结果:
_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查询实现这一目标?
答案 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 = [];
}