【问题标题】:MongoDB how to find nearest neighborsMongoDB如何找到最近的邻居
【发布时间】:2017-04-06 05:26:06
【问题描述】:

我正在尝试使用 mongo 创建简单的排行榜。 我有使用 node.js 和 express 构建的 API。

现在我有按用户点排序的 json,如下所示:

[
    {
    "_id": "58e543758222ff220d0af481",
    "id": 5,
    "__v": 0,
    "name": "Frank",
    "points": 653
    },
    {
    "_id": "58e543758222ff220d0af479",
    "id": 1,
    "__v": 0,
    "name": "Bob",
    "points": 321
    },
    {
    "_id": "58e543758222ff220d0af47b",
    "id": 2,
    "__v": 0,
    "name": "John",
    "points": 123
    },
    {
    "_id": "58e543758222ff220d0af47d",
    "id": 3,
    "__v": 0,
    "name": "Bravo",
    "points": 34
    },
    {
    "_id": "58e543758222ff220d0af47f",
    "id": 4,
    "__v": 0,
    "name": "Bill",
    "points": 12
    }
]

我收到了如下所示的请求:

User.find().sort({ points: '-1' }).exec(function(err, users) {
    if (err)
        res.send(err);

    res.json(users);
});

还有另一个获取指定id的get请求。

User.findOne({id: req.params.id}, function(err, user) {
    if (err)
        res.send(err);
    res.json(user);
});

我只是发送用户 ID 并获取有关他的信息。 我不知道如何找到指定 id 的最近邻居。例如,我找到了 id: 3 的用户,但如何在他之前显示一位用户,在他之后使用积分显示一位用户。

谢谢

【问题讨论】:

    标签: node.js mongodb rest


    【解决方案1】:

    另一种方法是查询所有用户并使用结果集将其过滤掉。

    User.find().sort({ points: '-1' }).exec(function (err, users) {
        if (err)
            // probably good idea to add return to stop the code from going further
            return res.send(err);
    
        var nbd = [];
        for (var i = 0; i < users.length; i++) {
            // find the user with the given ID
            if (users[i].id == req.params.id) {
                // add user before him
                if (i-1 >= 0) {
                    nbd.push(users[i-1]);
                }
                // add user
                nbd.push(users[i]);
                // add user after him
                if (i+1 < users.length) {
                    nbd.push(users[i+1]);
                }
                // no need to search any further
                break;
            }
        }
    
        res.json(nbd);
    });
    

    【讨论】:

    • 你昨天救了我,你又来了。谢谢 :) 你能告诉我这个解决方案是否适用于例如 10000 个元素吗?我将每 2 小时发送一次此类请求。
    • 现在,我不知道。我使用 MongoDB 的次数越多,我就越发现它的局限性,最终不得不做一些奇怪的解决方案,比如这个。
    • 我刚刚在 9276 位用户上测试了这个解决方案,效果非常好 :)
    • 这个复杂度为 Θ(n),不好。它根本不会扩展。尝试寻找点数位于列表末尾的用户。
    【解决方案2】:

    这没有经过测试,只是一个想法:

    User.findOne({id: req.params.id}, function(err, user) {
        if (err)
            res.send(err);
    
        User.findOne({ "points": { "$gt": user.points } }, { "$orderby": { "points": -1 } }, 
            function(err, user_neigh_greater) {
                if (err)
                    res.send(err);
                res.json(user_neigh_greater);
        });
    
        User.findOne({ "points": { "$lt": user.points } }, { "$orderby": { "points": -1 } },
            function(err, user_neigh_lower) {
                if (err)
                    res.send(err);
                res.json(user_neigh_lower);
        });
    });
    

    找到第一个较低或较大的,按其点数排序。如果具有等于 points 值的邻居有效,则可以使用 $gte$lte

    【讨论】:

      猜你喜欢
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 1970-01-01
      相关资源
      最近更新 更多