获取MongoDB聚合框架中的数组交集的大小

时间:2013-08-06 01:04:43

标签: mongodb mongodb-java aggregation-framework

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

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

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

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

有办法做到这一点吗?

2 个答案:

答案 0 :(得分: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
}

请注意,我认为您只需要排名前所未有的匹配项,因为可能会有非常多的用户。 $ limit步骤后跟$ limit步骤将完成此操作。如果不是这种情况,那么您可以省略管道中的最后两个步骤。

我希望这有帮助!如果您还有其他问题,请与我们联系。

布鲁斯

答案 1 :(得分:1)

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

如果您正在进行两个数组(集合)的交集,则首先要使用$setIntersection运算符来查找两个数组的交集。另一个例子在this question中给出。

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