gpt4 book ai didi

mongodb - 按组连接字符串

转载 作者:可可西里 更新时间:2023-11-01 09:13:57 26 4
gpt4 key购买 nike

我想按 _id 对记录进行分组,并通过组合 client_id 值创建一个字符串。

以下是我的文档示例:

{
"_id" : ObjectId("59e955e633d64c81875bfd2f"),
"tag_id" : 1,
"client_id" : "10001"
}
{
"_id" : ObjectId("59e955e633d64c81875bfd30"),
"tag_id" : 1,
"client_id" : "10002"
}

我想要这样的输出:

{
"_id" : 1
"client_id" : "10001,10002"
}

最佳答案

您可以将聚合框架作为“两步”操作来完成。这是先通过 $push 将项目累加到数组中使用 $group管道,然后使用 $concat$reduce在最终投影中生成的阵列上:

db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
{ "$addFields": {
"client_id": {
"$reduce": {
"input": "$client_id",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ "$$value", "" ] },
"then": "$$this",
"else": {
"$concat": ["$$value", ",", "$$this"]
}
}
}
}
}
}}
])

我们还申请$cond此处是为了避免在结果中将空字符串与逗号连接起来,因此它看起来更像是一个分隔列表。

仅供引用,存在 JIRA 问题 SERVER-29339这确实要求 $reduce将作为 accumulator expression 实现允许它直接在 $group 中使用流水线阶段。不太可能很快发生,但理论上它会取代 $push在上面并使操作成为单个管道阶段。建议语法示例在 JIRA 问题上。

如果你没有 $reduce (需要 MongoDB 3.4)然后只对游标进行后处理:

db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
]).map( doc =>
Object.assign(
doc,
{ "client_id": doc.client_id.join(",") }
)
)

这会导致使用 mapReduce 执行此操作的另一种选择如果你真的必须:

db.collection.mapReduce(
function() {
emit(this.tag_id,this.client_id);
},
function(key,values) {
return [].concat.apply([],values.map(v => v.split(","))).join(",");
},
{ "out": { "inline": 1 } }
)

这当然以 _idvalue 作为键集的特定 mapReduce 形式输出,但它基本上是输出。

我们使用 [].concat.apply([],values.map(...)) 因为“reducer”的输出可以是一个“定界字符串”,因为 mapReduce 以增量方式处理大量结果,因此 reducer 的输出可以在另一遍中变成“输入”。因此,我们需要预料到这会发生并相应地对待它。

关于mongodb - 按组连接字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46841825/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com