在 mongo 聚合中将 ObjectID 转换为字符串
Convert ObjectID to String in mongo Aggregation
我现在处于这种情况:
我有一个 collection 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 转换为字符串?
编辑:
这是相关的,但我的解决方案不适合我的问题。 (特别是因为我不能在聚合期间使用 ObjectId.toString())
的确,我在Mongo的文档中找不到任何 ObjectId().toString() 操作,但我想知道在这种情况下是否可以做一些棘手的事情。
我找不到做我想做的事情的方法,所以我创建了一个 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'
}
);
您可以使用 $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字段,这个聚合returns数据是这样的。
{
"_id" => "28-9-2016",
"i" => 2
}
我认为您可以尝试使用包含两个字段的数组来解决它:
{$project:{newkey:['$userRef','$serialNumber']},{$match:{newkey:{$in:filterArray}}}}
这可能会将具有两个字段的数据都匹配到过滤器。请注意,newkey 数组中的数据应与 filterArray 元素具有相同的数据类型。
现在您可以尝试使用 $toString
聚合,这很简单
将 ObjectId 转换为字符串
db.collection.aggregate([
{ "$addFields": {
"userRef": { "$toString": "$userRef" }
}},
{ "$group": {
"_id": { "$concat": ["$userRef", "-", "$serialNumber"] }
}}
])
你可以检查输出here
您可以简单地使用 $toString 以下列方式在 ObjectID 上应用 $concat 聚合 -
$group: {
'_id': {
'$concat': [
{ '$toString' : '$userRef' },
'-',
{ '$toString' : '$serialNumber'}
]
},
}
我现在处于这种情况: 我有一个 collection 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 转换为字符串?
编辑:
这
的确,我在Mongo的文档中找不到任何 ObjectId().toString() 操作,但我想知道在这种情况下是否可以做一些棘手的事情。
我找不到做我想做的事情的方法,所以我创建了一个 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'
}
);
您可以使用 $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字段,这个聚合returns数据是这样的。
{
"_id" => "28-9-2016",
"i" => 2
}
我认为您可以尝试使用包含两个字段的数组来解决它:
{$project:{newkey:['$userRef','$serialNumber']},{$match:{newkey:{$in:filterArray}}}}
这可能会将具有两个字段的数据都匹配到过滤器。请注意,newkey 数组中的数据应与 filterArray 元素具有相同的数据类型。
现在您可以尝试使用 $toString
聚合,这很简单
将 ObjectId 转换为字符串
db.collection.aggregate([
{ "$addFields": {
"userRef": { "$toString": "$userRef" }
}},
{ "$group": {
"_id": { "$concat": ["$userRef", "-", "$serialNumber"] }
}}
])
你可以检查输出here
您可以简单地使用 $toString 以下列方式在 ObjectID 上应用 $concat 聚合 -
$group: {
'_id': {
'$concat': [
{ '$toString' : '$userRef' },
'-',
{ '$toString' : '$serialNumber'}
]
},
}