【问题标题】:Node, MongoDB : Incrementing values of items in array with range query节点,MongoDB:使用范围查询增加数组中项目的值
【发布时间】:2016-08-01 16:17:30
【问题描述】:

我在 mongodb 的 users 集合下有一个类别数组。

前端基本上有一个类别的拖放菜单,当发生拖放时我想更新数据库。由于无法在数组中移动项目,我决定在 mongodb 中给它们一个位置值“pos”,然后在 angularjs 中对它们进行排序。

categories: [
    {
        "_id" : ObjectId("5776782a57c9580256536656"),
        "title" : "Cars",
        "url" : "cars",
        "pos" : 0
    },
    {
        "_id" : ObjectId("5776786afdcd6ed056edff25"),
        "title" : "Photography",
        "url" : "photography",
        "nodes" : [ 
            {
                "_id" : ObjectId("57767870fdcd6ed056edff26"),
                "title" : "Landscape",
                "url" : "landscape"
            }
        ],
        "pos" : 1
    },
    {
        "_id" : ObjectId("adf9845782578a376161d079"),
        "title" : "Travel",
        "url" : "travel",
        "pos" : 2
    }
]

我使用 nodejs-express 作为服务器,这是我移动类别的代码。

  • oldIndex : 移动前类别的位置
  • newIndex : 移动后类别的新位置
  • userId : 用户对象 ID

    if (newIndex>oldIndex){
        db.collection('users').updateOne({ "_id": userId, "categories.pos": { $gte: oldIndex, $lt: newIndex } }, { $inc : { "categories.$.pos" : -1 } }, function (err, res) {
            console.log(res);
            if (err) callback(0)
            else {
                db.collection('users').updateOne(filter, { $set :  cdata }, function (err, res) {
                    if (err) callback(0);
                    callback(1);
                });
            }
        });
    } else {
        db.collection('users').updateOne({ "_id": userId, "categories.pos": { $gt: newIndex, $lte: oldIndex  } }, { $inc : { "categories.$.pos" : 1 } }, function (err, res) {
            console.log(res);
            if (err) callback(0)
            else {
                db.collection('users').updateOne(filter, { $set :  cdata }, function (err, res) {
                    if (err) callback(0);
                    callback(1);
                });
            }
        });
    }

基本上,代码就是这样做的

if (newIndex > oldIndex)

  • A 类 - 0(旧索引)
  • B 类 - 1
  • C 类 - 2
  • D 类 - 3

将 A 移动到索引 2

  • B 类 - 0 (-1)
  • C 类 - 1 (-1)
  • A 类 - 2(新索引)
  • D 类 - 3 (0)

反之亦然

if (oldIndex > newIndex)

  • A 类 - 0
  • B 类 - 1
  • C 类 - 2(旧索引)
  • D 类 - 3

将 C 移动到索引 0

  • C 类 - 0(新索引)
  • A 类 - 1 (+1)
  • B 类 - 2 (+1)
  • D 类 - 3 (0)

在这种情况下,我无法运行查找查询来查看查询结果并对其进行故障排除。

对于任意数量的类别,查询只会更新一个值。

我想我需要一双新的眼睛。

谢谢。

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

    MongoDB 保持数组的顺序。 那么如何删除数组中的元素并使用$position重新插入正确位置的元素

    查询移除元素:

    db.getCollection('users').update({
            "_id" : idusers
        },
        {
            $pull: {
                categories: {
                    field: foo //your field for grep the element
                }
            }
    })
    

    以及在他的新索引处设置元素的查询:

    db.getCollection('users').update(
        {
            "_id" : idusers
        },
        {
            $push: {
                categories: {
                   // Set just one element in the $each, that enable you to use $position
                    $each: [{
                        "title" : "Photography",
                        "url" : "photography",
                        "nodes" : [{
                                "_id" : ObjectId("57767870fdcd6ed056edff26"),
                                "title" : "Landscape",
                                "url" : "landscape"
                        }]
                    }],
                    $position: newIndex
                }
            }
        }
    )
    

    我做了一些手动测试,似乎可以工作

    【讨论】:

    • 感谢您的回答,非常感谢 如果一个类别有很多子类别,我猜这对性能不利。现在我正在从客户端发送类别的 id 和旧/新索引,所以请求很短,这样我必须从客户端发送移动项目的所有 json 或进行查找查询以获取类别身份证第一。昨天为了简短起见,我将整个类别的 json 从客户端发送到服务器以进行更新,您的解决方案是现在更好的替代方法。
    • 如果您认为解决了您的问题,请接受关闭问题的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2021-07-23
    • 2019-06-05
    • 2018-06-12
    • 1970-01-01
    相关资源
    最近更新 更多