我现在正处于这种情况: 我有一个集合X:
{
_id:ObjectId('56edbb4d5f084a51131dd4c6'),
userRef:ObjectId('56edbb4d5f084a51131dd4c6'),
serialNumber:'A123123',
...
}
我需要聚合所有文档,用userRef + serialNumber对它们进行分组,所以我试着像这样使用concat:
$group: {
_id: {
'$concat': ['$userRef','-','$serialNumber']
},
...
所以基本上在MongoDB的聚合中,我需要通过ObjectId和字符串的连接来分组文档。但是,似乎$ concat只接受字符串作为参数:
uncaught exception: aggregate failed: {
"errmsg" : "exception: $concat only supports strings, not OID",
"code" : 16702,
"ok" : 0
}
有没有办法将ObjectId转换为聚合表达式中的String?
修改:
此question是相关的,但我解决方案不符合我的问题。 (特别是因为我不能在聚合期间使用ObjectId.toString())
实际上我在Mongo的文档中找不到任何ObjectId()。toString()操作,但我想知道在这种情况下是否有任何棘手的事情可以做。
答案 0 :(得分:6)
我无法找到一种方法来做我想要的事情,所以我创建了一个MapReduce函数,最终以我想要的方式生成键(连接其他键)。
最后,它看起来像这样:
db.collection('myCollection').mapReduce(
function() {
emit(
this.userRef.str + '-' + this.serialNumber , {
count: 1,
whateverValue1:this.value1,
whateverValue2:this.value2,
...
}
)
},
function(key, values) {
var reduce = {}
.... my reduce function....
return reduce
}, {
query: {
...filters_here....
},
out: 'name_of_output_collection'
}
);
答案 1 :(得分:2)
现在,您可以尝试使用 $toString
聚合
将ObjectId转换为字符串
db.collection.aggregate([
{ "$addFields": {
"userRef": { "$toString": "$userRef" }
}},
{ "$group": {
"_id": { "$concat": ["$userRef", "-", "$serialNumber"] }
}}
])
您可以检查输出here
答案 2 :(得分:1)
您可以简单地使用 $ toString 通过以下方式在对象ID上聚合应用$ concat-
$group: {
'_id': {
'$concat': [
{ '$toString' : '$userRef' },
'-',
{ '$toString' : '$serialNumber'}
]
},
}
答案 3 :(得分:-1)
您可以使用$substr
https://docs.mongodb.com/manual/reference/operator/aggregation/substr/#exp._S_substr在$concat
之前将任何对象转换为字符串。
这是为我工作的代码示例。
group_id_i['_id'] = {
'$concat' => [
{ '$substr' => [ {'$year' => '$t'}, 0, -1] }, '-',
{ '$substr' => [ {'$month' => '$t'}, 0, -1] }, '-',
{ '$substr' => [ {'$dayOfMonth' => '$t'}, 0, -1] }
]
}
其中t
是DateTime字段,此聚合返回类似的数据。
{
"_id" => "28-9-2016",
"i" => 2
}