1

我目前在 Java Web 应用程序中使用 MongoDB 的聚合框架,根据其他用户的偏好为用户生成推荐。

我使用的主要方法之一是查看数组交集。

现在我的算法只是认为两个用户“相似”,如果他们有一个非零数组交集。

为了构建更准确的算法,我想将集合交集的大小权衡到我的聚合管道中。

有没有办法做到这一点?

4

2 回答 2

3

如果我理解您的问题,您的数据如下所示:

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 步骤将完成此操作。如果不是这种情况,那么您可以省略管道中的最后两个步骤。

我希望这有帮助!如果您还有其他问题,请告诉我。

布鲁斯

于 2013-09-17T19:23:58.013 回答
1

从 MongoDB 2.6+ 开始,您可以使用$size表达式。

如果您正在做两个数组(集合)的交集,您首先需要使用$setIntersection运算符来查找两个集合的交集。这个问题给出了另一个例子。

然后,您可以使用新的$size运算符来获取管道交叉阶段的输出大小。 这个答案提供了一个使用新的 $size 表达式的例子。

于 2015-03-03T19:10:18.743 回答