MongoDB 将接近的值组合在一起
MongoDB group close values together
我想在我的聚合管道中将接近的值组合在一起。类似于:如果我想要的距离是 2,那么我将遍历数组中的每个元素,如果当前元素和前一个元素之间的距离小于 2,则将它们分组。
示例:
数组是[1, 2, 4, 7, 8]
,我想要的距离是2.
首先,检查 2 - 1
是否小于或等于 2,以便将它们组合在一起。当前群组是[1, 2]
然后检查 4 - 2
是否小于或等于 2 ,因此 4 也被添加到组中。当前群组是[1, 2, 4]
然后检查 7 - 4
是否小于或等于 2 而不是,所以最后一组保持 [1, 2, 4]
现在在当前组,只有[7]
.
然后检查 8 - 7
是否小于或等于 2 所以第一组仍然是 [1, 2, 4]
而当前组是 [7, 8]
.
不知道说的够不够清楚,如果觉得不够详细请追问。
第一个挑战是定义组。一种解决方案是:
db.collection.aggregate([
{
$set: {
a: {
$reduce: {
input: "$a",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
val: "$$this",
group: {
$cond: {
if: { $lte: [{ $subtract: ["$$this", { $last: "$$value.val" }] }, 2] },
then: { $ifNull: [{ $last: "$$value.group" }, 0] },
else: { $add: [{ $last: "$$value.group" }, 1] }
}
}
}]
]
}
}
}
}
])
returns
"a" : [
{ "val" : 1, "group" : 0 },
{ "val" : 2, "group" : 0 },
{ "val" : 4, "group" : 0 },
{ "val" : 7, "group" : 1 },
{ "val" : 8, "group" : 1 }
]
然后你需要一些装饰品来使其进入最终结构:
db.collection.aggregate([
{
$set: {
a: {
$reduce: {
input: "$a",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
val: "$$this",
group: {
$cond: {
if: { $lte: [{ $subtract: ["$$this", { $last: "$$value.val" }] }, 2] },
then: { $ifNull: [{ $last: "$$value.group" }, 0] },
else: { $add: [{ $last: "$$value.group" }, 1] }
}
}
}]
]
}
}
}
}
},
{ $unwind: "$a" },
{ $group: { _id: "$a.group", data: { $push: "$a.val" } } },
{ $group: { _id: null, a: { $push: "$data" } } }
])
{
"_id": null,
"a": [
[1.0, 2.0, 4.0],
[7.0, 8.0]
]
}
我想在我的聚合管道中将接近的值组合在一起。类似于:如果我想要的距离是 2,那么我将遍历数组中的每个元素,如果当前元素和前一个元素之间的距离小于 2,则将它们分组。
示例:
数组是[1, 2, 4, 7, 8]
,我想要的距离是2.
首先,检查 2 - 1
是否小于或等于 2,以便将它们组合在一起。当前群组是[1, 2]
然后检查 4 - 2
是否小于或等于 2 ,因此 4 也被添加到组中。当前群组是[1, 2, 4]
然后检查 7 - 4
是否小于或等于 2 而不是,所以最后一组保持 [1, 2, 4]
现在在当前组,只有[7]
.
然后检查 8 - 7
是否小于或等于 2 所以第一组仍然是 [1, 2, 4]
而当前组是 [7, 8]
.
不知道说的够不够清楚,如果觉得不够详细请追问。
第一个挑战是定义组。一种解决方案是:
db.collection.aggregate([
{
$set: {
a: {
$reduce: {
input: "$a",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
val: "$$this",
group: {
$cond: {
if: { $lte: [{ $subtract: ["$$this", { $last: "$$value.val" }] }, 2] },
then: { $ifNull: [{ $last: "$$value.group" }, 0] },
else: { $add: [{ $last: "$$value.group" }, 1] }
}
}
}]
]
}
}
}
}
])
returns
"a" : [
{ "val" : 1, "group" : 0 },
{ "val" : 2, "group" : 0 },
{ "val" : 4, "group" : 0 },
{ "val" : 7, "group" : 1 },
{ "val" : 8, "group" : 1 }
]
然后你需要一些装饰品来使其进入最终结构:
db.collection.aggregate([
{
$set: {
a: {
$reduce: {
input: "$a",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
val: "$$this",
group: {
$cond: {
if: { $lte: [{ $subtract: ["$$this", { $last: "$$value.val" }] }, 2] },
then: { $ifNull: [{ $last: "$$value.group" }, 0] },
else: { $add: [{ $last: "$$value.group" }, 1] }
}
}
}]
]
}
}
}
}
},
{ $unwind: "$a" },
{ $group: { _id: "$a.group", data: { $push: "$a.val" } } },
{ $group: { _id: null, a: { $push: "$data" } } }
])
{
"_id": null,
"a": [
[1.0, 2.0, 4.0],
[7.0, 8.0]
]
}