MongoDB - 增加Object中的嵌套值

时间:2015-01-27 11:03:38

标签: mongodb mongodb-query aggregation-framework

请在文档

后考虑“group”集合
"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
            }

我需要从"54c5c59d75de3e8d0a8b4568"开始增加4个字段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 个答案:

答案 0 :(得分:3)

关于你如何接近这个问题,有些事情是非常错误的。最基本的是这不是一个数组,所以你需要了解差异。

  1. 数据作为关键名称。这些键值显然是从ObjectId值派生出来的,并且没有位置是对象中键的名称。这是一个糟糕的模式。密钥名称无法编制索引,只能索引数据。谁教你这是一个可行的设计模式,把它们发送给我,我会把它们直接设置。不要那样做。

  2. 您可以将数据呈现为一个数组,但是您不能真正说“从x开始接下来的四个”作为匹配的值,而不需要先执行其他查询工作,这需要大量开销。

  3. 鉴于上述两点,您应该只在集合中创建这些离散文档。用法不明确,但它可能是最干净的。


  4. 所以这就是我的意思:

    案例1


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

    "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不能在不使用JavaScript的情况下“遍历”文档“键”,这会导致性能非常差。

    案例2


    考虑到上述情况,您可以在文档中使用数组时始终执行此操作。它远非最佳,不推荐。

    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" }
        }}
    ])
    

    案例3


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

        { "_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);
    

    重点是你如何构建这个。使用“密钥”作为“值”的文档是一种应该避免的非常糟糕的模式。另外,数组的处理似乎也不是最佳的,即使它比前者更好,因为只有JavaScript遍历可用,我不会给出那个坏的例子。

    在最后的事件中,这表明即使是数组也不实用。最好的课程是使用简单的收藏。这使得标准运算符的查询选择变得简单快捷。

    更改构建和记录最佳执行ant选项的数据的方式。


    当然,所有这一切的最终情况是您需要根据所需条件“选择”要更新的项目,然后发出单独的“更新”语句,其中包含_id个值现有的“文件”或可能适用的“数组元素”。

    $limit这样的东西不能用作“更新”修饰符。但实际上有一个功能请求。所以它可能会在某一天发生。