如何按加权值排序

时间:2014-09-05 09:26:33

标签: javascript mongodb mongodb-query aggregation-framework

我有这个问题,我想根据另一个集合中的字段值对查询结果进行排序,

问题:我想首先让用户获得123位朋友,然后获取他们的帖子,然后使用朋友的力量值对帖子进行排序,

我有这个:

POST COLLECTON:
{
    user_id: 8976,
    post_text: 'example working',
}
{
    user_id: 673,
    post_text: 'something',
}

USER COLLECTON:
{
    user_id: 123,
    friends: {
        {user_id: 673,strength:4}
        {user_id: 8976,strength:1}
    }
}

1 个答案:

答案 0 :(得分:3)

根据您从用户处检索到的信息,您基本上希望看到如下所示的aggregation framework查询:

db.posts.aggregate([
    { "$match": { "user_id": { "$in": [ 673, 8976 ] } } },
    { "$project": {
        "user_id": 1,
        "post_text": 1,
        "weight": {
            "$cond": [
                { "$eq": [ "$user_id", 8976 ] },
                1,
                { "$cond": [ 
                    { "$eq": [ "$user_id", 673 ] },
                    4,
                    0
                ]}
            ]
        }
    }},
    { "$sort": { "weight": -1 } }
])

那么为什么聚合时这不会聚合?如您所见,聚合框架不仅仅是聚合。在这里,它被用于"项目"在文档中添加一个新字段,并使用" weight"排序。这允许您按照希望对它们进行排序的值对结果进行排序。

当然,您需要在生成的"中获取初始数据到此表单。你对任何数据做的方式。这需要几个步骤,但在这里我将介绍JavaScript的方法,这应该很容易转换为大多数语言

还假设您的实际"用户"看起来更像这样,这是有效的:

{
    "user_id": 123,
    "friends": [
        { "user_id": 673,  "strength": 4 },
        { "user_id": 8976, "strength": 1 }
    ]
}

从这样的对象中构建聚合管道:

// user is the structure shown above

var stack = [];
args = [];

user.friends.forEach(function(friend) {

    args.push( friend.user_id );

    var rec = {
        "$cond": [
            { "$eq": [ "user_id", friend.user_id ] },
            friend.strength
        ]
    };

    if ( stack.length == 0 ) {
        rec["$cond"].push(0);
    } else {
        var last = stack.pop();
        rec["$cond"].push( last );
    }

    stack.push( rec );

});


var pipeline = [
    { "$match": { "user_id": { "$in": args } } },
    { "$project": {
        "user_id": 1,
        "post_text": 1,
        "weight": stack[0]
    }},
    { "$sort": { "weight": -1 } }
];

db.posts.aggregate(pipeline);

这就是它的全部内容。现在你有了一些代码来浏览"朋友"对于一个用户,并构建另一个查询,以获得那些由"力量"加权的朋友的所有帖子。每个人的价值。

当然,只需移除或更改 $match ,即可保留"重量"对所有帖子的查询可以做同样的事情。投影你可以"浮动"所有的朋友"帖子到顶部。