MongoDB聚合将字符串数组连接到单个字符串
我们正在尝试将字符串数组“连接”到聚合中的单个字符串 给出了以下数据集: 收集1:MongoDB聚合将字符串数组连接到单个字符串,mongodb,aggregation-framework,string-concatenation,Mongodb,Aggregation Framework,String Concatenation,我们正在尝试将字符串数组“连接”到聚合中的单个字符串 给出了以下数据集: 收集1: { id: 1234, field: 'test' } 收集2: { id: 1111, collection1_id: 1234, name: 'Max' }, { id: 1112, collection1_id: 1234, name: 'Andy' } 当前结果(在查找等之后): 所需结果: { id: 1234, field: 'test', collec
{
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'
}
是否有可能将“collection2”连接到单个字符串?我们已尝试使用
$concat
,但它只接受字符串。若要展平此数组,需要将进程转移到客户端
mongo将在新版中提供一些新的展平选项,但可能是算术选项(平均值、最小值、最大值…)您的思路是正确的 只需在您的
$project
阶段添加一个
'collection2': {
'$reduce': {
'input': '$collection2',
'initialValue': '',
'in': {
'$concat': [
'$$value',
{'$cond': [{'$eq': ['$$value', '']}, '', ', ']},
'$$this']
}
}
}
注意:我们用于防止串联中出现前导的,
。
您也可以使用before
$reduce
作为$cond启动Mongo 4.4
的替代方法,$group
阶段有一个新的聚合操作符,允许在文档分组时自定义累积文档:
// { "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" }
蓄能器:
- 在字段
名称
上累加(累加项
)
- 初始化为空数组(
init
)
- 通过将新名称连接到已看到的名称来累加(
累加
和合并
)
- 最后将所有名称合并为一个字符串(
finalize
)
有时使用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(', ')
}))
Mongo3.2有什么解决方案吗?我没有权限访问$reduce
@Friedrich请您详细说明如何使用$substrCP
?
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(', ')
}))