【问题标题】:Efficiently updating records in MongoDB / pymongo (perhaps in-place?)有效地更新 MongoDB / pymongo 中的记录(可能就地?)
【发布时间】:2013-05-09 04:28:32
【问题描述】:

我正在像这样更新我的收藏中的记录:

for document in myDB.find():
    if compliesToSomeRule(document):
        myDB.update({'_id':document['_id']}, {'$set':{'something':'somevalue'}})

这是最有效的方法吗?

我必须将更新的第一个参数设置为文档的_id 似乎很奇怪,因为这是重新查询索引吗?

可以这么说,有没有办法“就地”更新?

【问题讨论】:

    标签: mongodb pymongo mongodb-update


    【解决方案1】:

    你所做的更新命令的第一部分本质上是你想要的“compliesToSomeRule”方法。例如,假设 compliesToSomeRule 定义如下:

    def compliesToSomeResult(doc):
        if doc['a'] == 0:
            return True
        else:
            return False
    

    然后你可以跳过这组,直接做

    myDB.update({ 'a' : 0 }, {'$set' : { 'x' : 'y' }})
    

    然后,这会将您的更新文档(第二个)应用到集合中字段 a 等于 0 的所有文档。

    另一个例子:如果你想找到所有 'a' > 0 的文档,你可以这样做

    myDB.update({ 'a' : { '$gt' : 0 }}, {'$set' : {'x' : 'y'}})
    

    更新调用的第一部分,即“查询”部分,是您指定哪些文档接收更新的方式。第二部分定义了更新的实际内容。

    以下文档可能会对您在查看此材料时有所帮助:http://docs.mongodb.org/manual/applications/update/

    【讨论】:

    • 这是个好主意。但通常我的 compilesToSomeRule 函数非常复杂,作为 finder 参数的一部分可能很难实现:/
    • 啊,这确实让事情变得更难了,也许如果你放一个描述你想要做什么的示例函数,我们可能会想出一个好的解决方案。话虽如此,我确实经常建议人们按照您在客户端描述的那样进行复杂的操作,所以也许您的原始解决方案(您问题中的那个)是处理此问题的最佳方法。
    【解决方案2】:

    您正在就地更新。 update 的第一个参数是一个 find 子句,这就是它识别要更新的记录的方式。

    编辑

    MongoDB 是否处理缓存? 是的。 MongoDB保留了所有最 RAM 中最近使用的数据。如果您已经为您的 查询和您的工作数据集适合 RAM,MongoDB 服务于所有 从内存中查询。

    MongoDB 没有实现查询缓存:MongoDB 服务于所有查询 直接来自索引和/或数据文件。


    另外,你的用户名很棒:)

    【讨论】:

    • 但是 find 子句必须重新查找记录...确定已经找到了?也许不是。 p.s. - 最好的 XKCD 嗯? :D
    • 我认为 Ian 的意思是更新调用的第一部分是执行“compliesToSomeRule”部分。在这种情况下,它是说 document._id == expected_id,非常基本/简单。但你可以这样做:myDB.update( { 'a' : 0 }, { '$set' : ....})。在这种情况下,您指定 a == 0。执行该更新将修改 a == 0 的任何文档,这与您的“compliesToSomeRule”方法相同。编辑:我要写一个更完整的答案...
    【解决方案3】:

    我想你想看看“$where”关键字。 http://docs.mongodb.org/manual/reference/operator/where/ 它允许您基于 javascript 函数进行查询,因此一切都发生在数据库上。不过这可能会慢一些。

    【讨论】:

      【解决方案4】:

      如果你需要找到一个特定的文档然后添加一些东西:

          flag=db.foo.find({"_id":333})
          try: 
              if flag[0]['_id']:
                  db.foo.update({"_id":333},{"$set":{"name":"mongo"}})
          except:
              print "none"
      

      但如果您需要搜索所有文档并添加一些内容:

      flag=db.foo.find()
      for row in flag:
          db.foo.update({"_id":flag['_id']},{"$set":{"name":"mongo"}})
      

      【讨论】:

        猜你喜欢
        • 2021-04-25
        • 1970-01-01
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 2018-01-02
        • 2011-10-28
        • 1970-01-01
        • 2018-01-11
        相关资源
        最近更新 更多