我目前在 Java Web 应用程序中使用 MongoDB 的聚合框架,根据其他用户的偏好为用户生成推荐。
我使用的主要方法之一是查看数组交集。
现在我的算法只是认为两个用户“相似”,如果他们有一个非零数组交集。
为了构建更准确的算法,我想将集合交集的大小权衡到我的聚合管道中。
有没有办法做到这一点?
我目前在 Java Web 应用程序中使用 MongoDB 的聚合框架,根据其他用户的偏好为用户生成推荐。
我使用的主要方法之一是查看数组交集。
现在我的算法只是认为两个用户“相似”,如果他们有一个非零数组交集。
为了构建更准确的算法,我想将集合交集的大小权衡到我的聚合管道中。
有没有办法做到这一点?
如果我理解您的问题,您的数据如下所示:
db.users.insert({_id: 100, likes: [
'pina coladas',
'long walks on the beach',
'getting caught in the rain'
]})
db.users.insert({_id: 101, likes: [
'cheese',
'bowling',
'pina coladas'
]})
db.users.insert({_id: 102, likes: [
'pina coladas',
'long walks on the beach'
]})
db.users.insert({_id: 103, likes: [
'getting caught in the rain',
'bowling'
]})
db.users.insert({_id: 104, likes: [
'pina coladas',
'long walks on the beach',
'getting caught in the rain'
]})
并且您希望为给定用户计算他们与其他用户有多少匹配特征(在本例中为“喜欢”)?以下聚合管道将完成此操作:
user = 100
user_likes = db.users.findOne({_id: user}).likes
return_only = 2 // number of matches to return
db.users.aggregate([
{$unwind: '$likes'},
{$match: {
$and: [
{_id: {$ne: user}},
{likes: {$in: user_likes}}
]
}},
{$group: {_id: '$_id', common: {$sum: 1}}},
{$sort: {common: -1}},
{$limit: return_only}
])
鉴于上面的示例输入数据,这将输出以下结果,显示前 2 个匹配项:
{
"result" : [
{
"_id" : 104,
"common" : 3
},
{
"_id" : 102,
"common" : 2
}
],
"ok" : 1
}
请注意,我假设您只需要前那么多匹配项,因为可能有非常多的用户。$sort 步骤后跟 $limit 步骤将完成此操作。如果不是这种情况,那么您可以省略管道中的最后两个步骤。
我希望这有帮助!如果您还有其他问题,请告诉我。
布鲁斯
从 MongoDB 2.6+ 开始,您可以使用$size表达式。
如果您正在做两个数组(集合)的交集,您首先需要使用$setIntersection运算符来查找两个集合的交集。这个问题给出了另一个例子。
然后,您可以使用新的$size运算符来获取管道交叉阶段的输出大小。 这个答案提供了一个使用新的 $size 表达式的例子。