我们正在尝试将一个字符串数组'连接'到聚合内的单个字符串。
给出以下数据集:
收集1:
{
id: 1234,
field: 'test'
}
收集2:
{
id: 1111,
collection1_id: 1234,
name: 'Max'
},
{
id: 1112,
collection1_id: 1234,
name: 'Andy'
}
当前结果(查找后等):
{
id: 1234,
field: 'test',
collection2: ['Max', 'Andy']
}
所需的结果:
{
id: 1234,
field: 'test',
collection2: 'Max, Andy'
}
以某种方式可以将'collection2'加入单个字符串吗?我们尝试使用$concat
,但它只接受字符串。
答案 0 :(得分:8)
你走在正确的轨道上。
只需在$project
阶段的$reduce上添加$concat。
'collection2': {
'$reduce': {
'input': '$collection2',
'initialValue': '',
'in': {
'$concat': [
'$$value',
{'$cond': [{'$eq': ['$$value', '']}, '', ', ']},
'$$this']
}
}
}
注意:我们使用$cond来阻止串联中的前导,
。
您也可以在$reduce
之前使用$substrCP作为$cond
的替代。
答案 1 :(得分:0)
要展平此数组,您需要将流程转移到客户端。
mongo将在新版本中提供一些新的展平选项,但是afaik将是算术版(avg,min,max ....)。
答案 2 :(得分:0)
从Mongo 4.4
开始,$group
阶段有了一个新的聚合运算符$accumulator
,允许在文件分组时进行自定义累积:
// { "collectionId" : 1234, "name" : "Max" }
// { "collectionId" : 876, "name" : "Rob" }
// { "collectionId" : 1234, "name" : "Andy" }
db.collection.aggregate([
{ $group: {
_id: "$collectionId",
names: {
$accumulator: {
accumulateArgs: ["$name"],
init: function() { return [] },
accumulate: function(names, name) { return names.concat(name) },
merge: function(names1, names2) { return names1.concat(names2) },
finalize: function(names) { return names.join(",") },
lang: "js"
}
}
}}
])
// { "_id" : 876, "names" : "Rob" }
// { "_id" : 1234, "names" : "Max,Andy" }
累加器:
name
(accumulateArgs
)字段上init
)accumulate
和merge
)来积累finalize
)答案 3 :(得分:0)
有时候使用JavaScript最简单:
db.getCollection('Collection1').aggregate([
{
$lookup:
{
from: 'Collection2',
localField: 'id',
foreignField: 'collection1_id',
as: 'col2'
}
}]).map((e) => ({
id: e.id,
field: e.field,
collection2: Array.isArray(e.col2) &&
e.col2.reduce((arr, el) => {
arr.push(el.name);
return arr;
}, []).join(', ')
}))