$group mongodb 后获取常用元素
Posted
技术标签:
【中文标题】$group mongodb 后获取常用元素【英文标题】:Get common elements after $group mongodb 【发布时间】:2019-11-29 15:49:25 【问题描述】:我有一些交易数据如下:
[
"_id" : ObjectId("5d319aa8df4026532fe5036f"),
"transaction" : ISODate("2018-10-16T04:00:07.000Z"),
"cardnumber" : "1000 0000 0002 0356"
,
"_id" : ObjectId("5d319aa8df4026532fe5035x"),
"transaction" : ISODate("2018-10-16T04:00:07.000Z"),
"cardnumber" : "1000 0000 0002 0358"
,
"_id" : ObjectId("5d319aa8df4026532fe5036d"),
"transaction" : ISODate("2018-09-16T04:00:07.000Z"),
"cardnumber" : "1000 0000 0002 0356"
]
我必须得到所有每月至少使用一次的卡号。
所以我的第一个想法是按月和年对它们进行分组:
return transactionsModel.aggregate([
$group:
_id:
year:
$year: "$transaction"
,
month:
$month: "$transaction"
,
results:
$push: '$$CURRENT.cardnumber'
,
]).allowDiskUse(true);
那个查询的答案是这样的:
[
"_id":
"year": 2018,
"month": 9
,
"results": [
"1000 0000 0002 0356"
]
,
"_id":
"year": 2018,
"month": 10
,
"results": [
"1000 0000 0002 0356",
"1000 0000 0002 0358"
]
]
但我不知道之后如何找到每个群体中通用的卡号。
期待回应:
"results": [
"1000 0000 0002 0356"
]
提前感谢您的回答。如果您需要任何其他信息,请询问,我会尽力提供。
【问题讨论】:
【参考方案1】:您可以将结果相交以获得预期结果
var result = [
"_id":
"year": 2018,
"month": 9
,
"results": [
"1000 0000 0002 0356"
]
,
"_id":
"year": 2018,
"month": 10
,
"results": [
"1000 0000 0002 0356",
"1000 0000 0002 0358"
]
]
const resultData = result.map(r => r.results)
function intersection(a)
if (a.length > 2)
return intersection([intersection(a.slice(0, a.length / 2)), intersection(a.slice(a.length / 2))]);
if (a.length == 1)
return a[0];
return a[0].filter(function(item)
return a[1].indexOf(item) !== -1;
);
console.log(intersection(resultData))
【讨论】:
【参考方案2】:你可以使用下面的聚合
db.collection.aggregate([
"$group":
"_id":
"year": "$year": "$transaction" ,
"month": "$month": "$transaction"
,
"results": "$push": "$$CURRENT.cardnumber"
,
"$group":
"_id": null,
"result": "$first": "$results" ,
"results": "$push": "$results"
,
"$project":
"results":
"$reduce":
"input": "$results",
"initialValue": "$result",
"in": "$setIntersection": ["$$value", "$$this"]
])
Output
[
"_id": null,
"results": [
"1000 0000 0002 0356"
]
]
【讨论】:
【参考方案3】:下面的实现会得到所有每月至少使用过一次的卡号。
let elements = [
"_id":
"year": 2018,
"month": 9
,
"results": [
"1000 0000 0002 0356"
]
,
"_id":
"year": 2018,
"month": 10
,
"results": [
"1000 0000 0002 0356",
"1000 0000 0002 0358"
]
];
let result =
"results": []
let found = [];
function findUsedCardNumbers()
elements.forEach(element =>
let card_numbers = element["results"];
for (let i = 0; i < card_numbers.length; i++)
if (isCardNumberContains(card_numbers[i]) && !found.includes(card_numbers[i]))
found.push(card_numbers[i])
);
result["results"] = found;
function isCardNumberContains(card_number)
let flag = true
try
elements.forEach(element =>
flag = (element["results"].includes(card_number)) ? true : false;
if (!flag)
throw BreakException;
);
catch (e)
return flag;
findUsedCardNumbers();
console.log(result);
预期结果将是:
"results": [
"1000 0000 0002 0356"
]
【讨论】:
以上是关于$group mongodb 后获取常用元素的主要内容,如果未能解决你的问题,请参考以下文章