我有与客户互动的产品的此文档(没有重复的产品):
{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "2"}, {"productType": "B", "productId": "9"}]}
{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "2"}]}
{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "3"}, {"productType": "C", "productId": "10"}]}
我想计算类型“ A”的每个产品的同现计数,如果客户与两个产品同时交互,则产品“ 1”与产品“ 2”同时存在。
就像是:
{ "co-ocurrences-count" : { "1" : [{ "2": 2}, { "3" : 1}]}, { "2" : [{ "1": 2}]}, { "3" : [{ "1": 1}]}}
我有一个使用map-reduce javascript函数的解决方案,但我真的希望它使用MongoDB聚合框架来实现,这可能吗?
提前致谢。
聚合时间很长,但是可以正常工作。这个想法是,您需要(x,y)
基于client_interactions
数组构建对。可以使用$ reduce和$ map来完成。然后,您需要运行$ unwind和几个$ group阶段来“缠绕”汇总数据。您还需要$ arrayToObject动态生成密钥。
db.collection.aggregate([
{
$addFields: {
"client_interactions": {
$filter: { input: "$client_interactions", cond: { $eq: [ "$$this.productType", "A" ] } }
}
}
},
{
$project: {
a: {
$reduce: {
input: "$client_interactions",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{ $map: { input: "$client_interactions", as: "c", in: { x: "$$this.productId", y: "$$c.productId" } } }
]
}
}
}
}
},
{
$unwind: "$a"
},
{
$match: {
$expr: {
$ne: [ "$a.x", "$a.y" ]
}
}
},
{
$sort: {
"a.x": 1,
"a.y": 1
}
},
{
$group: {
_id: "$a",
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.x",
arr: { $push: { k: "$_id.y", v: "$count" } }
}
},
{
$group: {
_id: null,
"co-ocurrences-count": { $push: { k: "$_id", v: { $arrayToObject: "$arr" } } }
}
},
{
$project: {
_id: 0,
"co-ocurrences-count": { $arrayToObject: "$co-ocurrences-count" }
}
}
])
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句