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
}
如果你有任何想法,请帮助我。
你处理这个问题的方式有几处是非常错误的。最基本的是这不是一个数组,所以你需要学习区别。
数据作为键名。这些键值显然是从 ObjectId 值派生的,并且没有地方是对象中键的名称。这是一个糟糕的模式。无法索引键名,只能索引数据。谁教你这是一个可行的设计模式,把它们发给我,我会把它们弄清楚。不要那样做。
您可以将数据呈现为数组,但您不能真正说 "get the next four starting from x" 作为要匹配的值,而不首先真正执行其他需要大量开销的查询工作。
鉴于以上两种情况,您可能应该将这些离散的文档放在一个集合中。用法不清楚,但大概是最干净的了。
所以这就是我的意思:
案例一
这不是最好的模式,您可能应该这样做,因为您无法查询名称的值:
"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" 修饰符。但实际上有一个功能请求。所以它可能有一天会发生。
请考虑"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
}
如果你有任何想法,请帮助我。
你处理这个问题的方式有几处是非常错误的。最基本的是这不是一个数组,所以你需要学习区别。
数据作为键名。这些键值显然是从 ObjectId 值派生的,并且没有地方是对象中键的名称。这是一个糟糕的模式。无法索引键名,只能索引数据。谁教你这是一个可行的设计模式,把它们发给我,我会把它们弄清楚。不要那样做。
您可以将数据呈现为数组,但您不能真正说 "get the next four starting from x" 作为要匹配的值,而不首先真正执行其他需要大量开销的查询工作。
鉴于以上两种情况,您可能应该将这些离散的文档放在一个集合中。用法不清楚,但大概是最干净的了。
所以这就是我的意思:
案例一
这不是最好的模式,您可能应该这样做,因为您无法查询名称的值:
"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" 修饰符。但实际上有一个功能请求。所以它可能有一天会发生。