假设我有一系列具有以下格式的文档:
{
"_id": "3_0",
"values": ["1", "2"]
}
我希望获得一个将数组值连接在单个字段中的投影:
{
"_id": "3_0",
"values": "1_2"
}
这种做法可行吗?我尝试了 $concat
,但我猜想我不能将 $values
作为 $concat
的数组。
假设我有一系列具有以下格式的文档:
{
"_id": "3_0",
"values": ["1", "2"]
}
我希望获得一个将数组值连接在单个字段中的投影:
{
"_id": "3_0",
"values": "1_2"
}
这种做法可行吗?我尝试了 $concat
,但我猜想我不能将 $values
作为 $concat
的数组。
$concat
,但是您可以使用$reduce
来处理数组元素并生成以下内容:db.collection.aggregate([
{ "$addFields": {
"values": {
"$reduce": {
"input": "$values",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ { "$indexOfArray": [ "$values", "$$this" ] }, 0 ] },
"then": { "$concat": [ "$$value", "$$this" ] },
"else": { "$concat": [ "$$value", "_", "$$this" ] }
}
}
}
}
}}
])
$indexOfArray
来避免在数组中的“第一个”索引处与 "_"
下划线不进行“连接”。
另外,我的额外“愿望”已经得到了 $sum
的回答。db.collection.aggregate([
{ "$addFields": {
"total": { "$sum": "$items.value" }
}}
])
db.collection.mapReduce(
function() {
emit( this._id, { "values": this.values.join("_") } );
},
function() {},
{ "out": { "inline": 1 } }
)
{
"items": [
{ "product": "A", "value": 1 },
{ "product": "B", "value": 2 },
{ "product": "C", "value": 3 }
]
}
总的来说:
db.collection.aggregate([
{ "$project": {
"total": { "$add": [
{ "$map": {
"input": "$items",
"as": "i",
"in": "$$i.value"
}}
]}
}}
])
$add
期望参数而不是来自文档的数组。叹气!:(。这种设计的一部分原因可以认为是“仅仅因为”从转换结果中传递了一个单值的“数组”或“列表”,并不能“保证”这些值实际上是运算符预期的有效的单一数字类型值。至少在当前实现的“类型检查”方法中不是这样的。
这意味着目前我们仍然需要这样做:
db.collection.aggregate([
{ "$unwind": "$items" },
{ "$group": {
"_id": "$_id",
"total": { "$sum": "$items.value" }
}}
])
很遗憾,目前没有方法可以应用这样的分组运算符来连接字符串。
因此,您可以期望在这方面进行某种变化,或者希望某些变化允许在$map
操作的范围内改变外部作用域变量。更好的是,一个新的$join
操作也会受到欢迎。但是,目前还不存在这些操作,而且可能在未来一段时间内都不会存在。
从Mongo 4.4开始,$function
聚合操作符允许应用自定义的JavaScript函数来实现MongoDB查询语言不支持的行为。
例如,为了连接一个字符串数组:
// { "_id" : "3_0", "values" : [ "1", "2" ] }
db.collection.aggregate(
{ $set:
{ "values":
{ $function: {
body: function(values) { return values.join('_'); },
args: ["$values"],
lang: "js"
}}
}
}
)
// { "_id" : "3_0", "values" : "1_2" }
$function
需要三个参数:
body
,它是要应用的函数,它的参数是要连接的数组。args
,其中包含记录中body
函数作为参数所需的字段。在我们的情况下是"$values"
。lang
,它是body
函数编写的语言。目前只有js
可用。