MongoDB - 增加 Object 中的嵌套值

MongoDB - Increase nested values in Object

请考虑"group" collection以下文档

"auto_availability" : {
                "54c5c59d75de3e8d0a8b4567" : 12,
                "54c5c59d75de3e8d0a8b4568" : 12,
                "54c5c59d75de3e8d0a8b4569" : 12,
                "54c5c59d75de3e8d0a8b456a" : 12,
                "54c5c59d75de3e8d0a8b456b" : 12,
                "54c5c59d75de3e8d0a8b456c" : 12,
                "54c5c59d75de3e8d0a8b456d" : 12,
                "54c5c59d75de3e8d0a8b456e" : 12,
                "54c5c59d75de3e8d0a8b456f" : 12,
                "54c5c59d75de3e8d0a8b4570" : 12,
                "54c5c59d75de3e8d0a8b4571" : 12,
                "54c5c59d75de3e8d0a8b4572" : 12,
                "54c5c59d75de3e8d0a8b4573" : 12,
                "54c5c59d75de3e8d0a8b4574" : 12,
                "54c5c59d75de3e8d0a8b4575" : 12,
                "54c5c59d75de3e8d0a8b4576" : 12,
                "54c5c59d75de3e8d0a8b4577" : 12,
                "54c5c59d75de3e8d0a8b4578" : 12
            }

我需要将 4 个字段从 "54c5c59d75de3e8d0a8b4568" 开始增加 10。

预期结果:

"auto_availability" : {
                "54c5c59d75de3e8d0a8b4567" : 12,
                "54c5c59d75de3e8d0a8b4568" : 22,
                "54c5c59d75de3e8d0a8b4569" : 22,
                "54c5c59d75de3e8d0a8b456a" : 22,
                "54c5c59d75de3e8d0a8b456b" : 22,
                "54c5c59d75de3e8d0a8b456c" : 12,
                "54c5c59d75de3e8d0a8b456d" : 12,
                "54c5c59d75de3e8d0a8b456e" : 12,
                "54c5c59d75de3e8d0a8b456f" : 12,
                "54c5c59d75de3e8d0a8b4570" : 12,
                "54c5c59d75de3e8d0a8b4571" : 12,
                "54c5c59d75de3e8d0a8b4572" : 12,
                "54c5c59d75de3e8d0a8b4573" : 12,
                "54c5c59d75de3e8d0a8b4574" : 12,
                "54c5c59d75de3e8d0a8b4575" : 12,
                "54c5c59d75de3e8d0a8b4576" : 12,
                "54c5c59d75de3e8d0a8b4577" : 12,
                "54c5c59d75de3e8d0a8b4578" : 12
            }

如果你有任何想法,请帮助我。

你处理这个问题的方式有几处是非常错误的。最基本的是这不是一个数组,所以你需要学习区别。

  1. 数据作为键名。这些键值显然是从 ObjectId 值派生的,并且没有地方是对象中键的名称。这是一个糟糕的模式。无法索引键名,只能索引数据。谁教你这是一个可行的设计模式,把它们发给我,我会把它们弄清楚。不要那样做。

  2. 您可以将数据呈现为数组,但您不能真正说 "get the next four starting from x" 作为要匹配的值,而不首先真正执行其他需要大量开销的查询工作。

  3. 鉴于以上两种情况,您可能应该将这些离散的文档放在一个集合中。用法不清楚,但大概是最干净的了。


所以这就是我的意思:

案例一


这不是最好的模式,您可能应该这样做,因为您无法查询名称的值:

"auto_availability" : [
    { "_id": "54c5c59d75de3e8d0a8b4567", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b4568", "value": 12 },  // <-- Maybe start here
    { "_id": "54c5c59d75de3e8d0a8b4569", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456a", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456b", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456c", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456d", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456e", "value": 12 }
]

这比您开始的情况好多了,因为遍历可以在数组元素内解决一些问题,主要是因为 MongoDB 不能 "walk" 不使用 [=76] 文档 "keys" =],导致性能很差。

案例二


考虑到上述情况,在文档中使用数组时,您始终可以这样做。它远非最佳,不推荐。

db.collection.aggregate([
    // Match possible documents
    { "$match": { 
        "auto_availibility._id": { "$gte": "54c5c59d75de3e8d0a8b4568" }
    }},

    // Unwind the array
    { "$unwind": "$auto_availabilty" },

    // Filter the documents from the de-normalized array
    { "$match": { 
        "auto_availibility._id": { "$gte": "54c5c59d75de3e8d0a8b4568" }
    }},

    // Keep the current 4 items only
    { "$limit": 4 },

    // Maybe group back to the document in an array
    { "$group": {
        "_id": "$_id",
        "auto_availability": { "$push": "$auto_availability" }
    }}
])

案例三


更好的是,在像这样的单独集合中:

    { "_id": "54c5c59d75de3e8d0a8b4567", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b4568", "value": 12 },  // <-- Maybe start here
    { "_id": "54c5c59d75de3e8d0a8b4569", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456a", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456b", "value": 12 },
    { "_id": "54c5c59d75de3e8d0a8b456c", "value": 12 },

现在非常简单的查询:

db.collection.find({
    "_id": { "$gte": "54c5c59d75de3e8d0a8b4568" }
}).limit(4);

要点是关于如何构建它。使用 "keys" 作为它们应该 "values" 的文档是一个非常糟糕的模式,应该避免。此外,数组的处理似乎也不是最佳的,即使它比前者更好,因为只有 JavaScript 遍历可用,我不会举那个坏的例子。

在最后的事件中,这说明即使是数组也不实用。最好的方法是使用普通集合。这使得使用标准运算符的查询选择变得简单和快速。

更改结构和记录数据的方式以获得最佳性能蚂蚁选项。


当然,所有这一切的最终情况是您需要 'select' 您想要根据您想要的标准更新的项目,然后发出一个单独的 "update" 声明 _id 当前 "documents" 或可能 "array elements" 的值(视情况而定)。

遗憾的是 $limit 之类的东西不能用作 "update" 修饰符。但实际上有一个功能请求。所以它可能有一天会发生。