mongodb aggregation 获取数组中负序的最大个数
mongodb aggregation get max number of negative sequence in array
我需要通过聚合从数组中获取负序列的最大计数,示例文档:
{
"id": 1,
x: [ 1,1,-1,-1,1,1,1,-1,-1,-1,-1]
},
{
"id": 2,
x: [ 1,-1,-1,1,1,1,-1 ]
}
预期结果:
{"id": 1,x:4},
{"id": 2,x:2}
请指教?
您可以使用 $reduce to iterate the array and $cond 来应用您的逻辑(连续否定)
载体格式
{
previous: // previous value to compare for continuity
acc: // number of consecutive negatives in the current sequence
max: // length of the longest sequence
}
$let 是为了记忆当前累加器以在最大计算中重用。它是可选的但方便:
db.collection.aggregate([
{
"$set": {
"x": {
"$reduce": {
"input": "$x",
"initialValue": {
previous: 0,
acc: 0,
max: 0
},
"in": {
$let: {
vars: {
result: {
"$cond": {
"if": {
"$and": [
{
"$lt": [
"$$this",
0
]
},
{
"$lt": [
"$$value.previous",
0
]
}
]
},
"then": {
"$add": [
"$$value.acc",
1
]
},
"else": {
"$cond": {
"if": {
"$lt": [
"$$this",
0
]
},
"then": 1,
"else": 0
}
}
}
}
},
in: {
previous: "$$this",
acc: "$$result",
max: {
"$cond": {
"if": {
$gt: [
"$$value.max",
"$$result"
]
},
"then": "$$value.max",
"else": "$$result"
}
}
}
}
}
}
}
}
},
{
"$set": {
x: "$x.max"
}
}
])
在 mongoplayground.net 上试用。
这是另一种方法。总体思路是将序列 $reduce
到一个字符串,然后 $split
使数组填充每个 运行 的字符串。然后将字符串数组映射到字符串长度数组,然后取最大值
db.collection.aggregate({
"$project": {
"_id": 0,
"id": 1,
"x": {
"$max": {
"$map": {
"input": {
$split: [
{
"$reduce": {
"input": "$x",
"initialValue": "",
"in": {
$concat: [
"$$value",
{
"$cond": [
{
"$gt": [
"$$this",
0
]
},
"p",
"n"
]
}
]
}
}
},
"p"
]
},
"in": {
"$strLenBytes": "$$this"
}
}
}
}
}
})
在 mongoplayground.net 上试用。
我需要通过聚合从数组中获取负序列的最大计数,示例文档:
{
"id": 1,
x: [ 1,1,-1,-1,1,1,1,-1,-1,-1,-1]
},
{
"id": 2,
x: [ 1,-1,-1,1,1,1,-1 ]
}
预期结果:
{"id": 1,x:4},
{"id": 2,x:2}
请指教?
您可以使用 $reduce to iterate the array and $cond 来应用您的逻辑(连续否定)
载体格式
{
previous: // previous value to compare for continuity
acc: // number of consecutive negatives in the current sequence
max: // length of the longest sequence
}
$let 是为了记忆当前累加器以在最大计算中重用。它是可选的但方便:
db.collection.aggregate([
{
"$set": {
"x": {
"$reduce": {
"input": "$x",
"initialValue": {
previous: 0,
acc: 0,
max: 0
},
"in": {
$let: {
vars: {
result: {
"$cond": {
"if": {
"$and": [
{
"$lt": [
"$$this",
0
]
},
{
"$lt": [
"$$value.previous",
0
]
}
]
},
"then": {
"$add": [
"$$value.acc",
1
]
},
"else": {
"$cond": {
"if": {
"$lt": [
"$$this",
0
]
},
"then": 1,
"else": 0
}
}
}
}
},
in: {
previous: "$$this",
acc: "$$result",
max: {
"$cond": {
"if": {
$gt: [
"$$value.max",
"$$result"
]
},
"then": "$$value.max",
"else": "$$result"
}
}
}
}
}
}
}
}
},
{
"$set": {
x: "$x.max"
}
}
])
在 mongoplayground.net 上试用。
这是另一种方法。总体思路是将序列 $reduce
到一个字符串,然后 $split
使数组填充每个 运行 的字符串。然后将字符串数组映射到字符串长度数组,然后取最大值
db.collection.aggregate({
"$project": {
"_id": 0,
"id": 1,
"x": {
"$max": {
"$map": {
"input": {
$split: [
{
"$reduce": {
"input": "$x",
"initialValue": "",
"in": {
$concat: [
"$$value",
{
"$cond": [
{
"$gt": [
"$$this",
0
]
},
"p",
"n"
]
}
]
}
}
},
"p"
]
},
"in": {
"$strLenBytes": "$$this"
}
}
}
}
}
})
在 mongoplayground.net 上试用。