在MongoDB中将不同的金额分组在一起



如果我有一组对象,每个对象都有相同的描述,但数量不同。

{
{
"_id": "101",
"description": "DD from my employer1",
"amount": 1000.33
},
{
"_id": "102",
"description": "DD from my employer1",
"amount": 1000.34
},
{
"_id": "103",
"description": "DD from my employer1",
"amount": 1000.35
},
{
"_id": "104",
"description": "DD from employer1",
"amount": 5000.00
},
{
"_id": "105",
"description": "DD from my employer2",
"amount": 2000.33
},
{
"_id": "106",
"description": "DD from my employer2",
"amount": 2000.33
},
{
"_id": "107",
"description": "DD from my employer2",
"amount": 2000.33
}
}

下面,我能够使用以下描述对它们进行分组:

{
{
"$group": {
"_id": {
"description": "$description"
},
"count": {
"$sum": 1
},
"_id": {
"$addToSet": "$_id"
}
}
},
{
"$match": {
"count": {
"$gte": 3
}
}
}
}

有没有办法包括组中的所有金额(_ids:101、102 和 103 加上 105,106,107),即使它们的差异很小,但不包括奖金金额,在上面的示例中是 _id 104?

我不认为可以在小组赛阶段完成,但是在稍后阶段是否可以将101,102和103分组_ids并排除_id 104。 基本上,我希望MongoDB忽略101,102,103中的微小差异,并将它们组合在一起,因为这些薪水来自同一雇主。

我一直在与$stdDevPop合作,但无法得到一个可靠的公式。

我正在寻找一个仅_ids的简单数组输出。

{ "结果":[ "101", "102", "103", "105", "106", "107" ] }

您可以通过对"金额"进行一些数学运算来将其四舍五入到最接近的 1000 并将其用作分组_id

db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$trunc": "$amount" },
{ "$mod": [
{ "$trunc": "$amount" }, 
1000
]}
]
},
"results": { "$push": "$_id" }
}},
{ "$redact": {
"$cond": {
"if": { "$gt": [ { "$size": "$results" }, 1 ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$unwind": "$results" },
{ "$group": {
"_id": null,
"results": { "$push": "$results" }
}}
])

如果你的MongoDB早于3.2,那么你只需要使用一个长形式来$mod$trunc正在做的事情。如果你的MongoDB早于2.6,那么你$match而不是$redact。所以在更长的形式中,这是:

db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [
"$amount",
{ "$mod": [ "$amount", 1 ] }
]},
{ "$mod": [
{ "$subtract": [
"$amount",
{ "$mod": [ "$amount", 1 ] }
]},
1000
]}
]
},
"results": { "$push": "$_id" },
"count": { "$sum": 1 }
}},
{ "$match": { "count": { "$gt": 1 } } },
{ "$unwind": "$results" },
{ "$group": {
"_id": null,
"results": { "$push": "$results" }
}}
])

无论哪种方式,输出都只是_id值,其数量分组到边界,计数不止一次。

{ "_id" : null, "results" : [ "105", "106", "107", "101", "102", "103" ] }

您可以在其中添加一个$sort,也可以在客户端代码中对结果数组进行排序。

db.yourDBNameHere.aggregate( [
{ $match: { "amount" : { $lt : 5000 } } },
{ $project: { _id: 1 } },
])

这将仅获取每笔低于 5000 美元的交易的 ID。

最新更新