Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pyMongo升级更新文档的多个字段,包括列表和嵌套列表_Python_Mongodb_Mongodb Query_Pymongo - Fatal编程技术网

Python 使用pyMongo升级更新文档的多个字段,包括列表和嵌套列表

Python 使用pyMongo升级更新文档的多个字段,包括列表和嵌套列表,python,mongodb,mongodb-query,pymongo,Python,Mongodb,Mongodb Query,Pymongo,我收集了如下文件: { "_id" : "1234567890", "area" : "Zone 63", "last_state" : "Cloudy", "recent_indices" : [ 21, 18, 33, ... 38 41 ], "Report_stats" : [ { "date_hour" : "2017-01-01 01",

我收集了如下文件:

{
"_id"    : "1234567890",
"area"   : "Zone 63",
"last_state" : "Cloudy",
"recent_indices" : [
        21,
        18,
        33,
        ...
        38
        41
  ],

"Report_stats" : [
 {
        "date_hour" : "2017-01-01 01",
        "count"     : 31
     },
 {
        "date_hour" : "2017-01-01 02",
        "count"     : 20
     },
        ...
     {
        "date_hour" : "2018-08-26 13",
        "count"     : 3
     }     
  ]
}
{
 'datetime' : '2018-08-26 13:48:11.677635',
 'areas'    : 'Zone 3; Zone 45; Zone 63',
 'status'   : 'Clear',
 'index'    : '33'
 }
update_one( {'_id':1}, {$set:{}}, upsert=True )
应该根据一些在线实时报告进行更新 假设每个报告如下所示:

{
"_id"    : "1234567890",
"area"   : "Zone 63",
"last_state" : "Cloudy",
"recent_indices" : [
        21,
        18,
        33,
        ...
        38
        41
  ],

"Report_stats" : [
 {
        "date_hour" : "2017-01-01 01",
        "count"     : 31
     },
 {
        "date_hour" : "2017-01-01 02",
        "count"     : 20
     },
        ...
     {
        "date_hour" : "2018-08-26 13",
        "count"     : 3
     }     
  ]
}
{
 'datetime' : '2018-08-26 13:48:11.677635',
 'areas'    : 'Zone 3; Zone 45; Zone 63',
 'status'   : 'Clear',
 'index'    : '33'
 }
update_one( {'_id':1}, {$set:{}}, upsert=True )
现在,我必须以以下方式更新集合:

  • 每次报告上出现一个新的“区域”(如区域1025)时,都会添加一个新文档来保存相关数据
  • 新的“索引”添加到“最近的索引”列表中,“最后的状态”更新为“状态”
  • 根据“datetime”是什么,相应的“Report_stats.count”增加1或插入一个新的“Report_stats”文档(“datetime”具有小时分辨率,其中“count”为1)
  • 单独执行这些更新的方法在某种程度上是显而易见的,问题是:如何在单个更新/升级任务中同时执行所有这些更新

    我尝试使用pyMongo使用
    update\u one
    find\u one和\u update
    (以及
    update
    find\u和\u modify
    ),但不可能(至少对我来说)解决问题

    所以我开始怀疑是否有一个简单/单一的任务可以完成,或者我应该开始尝试用一种完全不同的方式来修复它

    你能帮我怎么做吗?或者(因为收集了大量数据,因此需要处理)建议一种低成本的替代方案


    谢谢大家!

    我不确定我是否理解您的问题,但是如果您的问题围绕着upsert(即更新它)或添加记录(如果它不存在)。 您可以通过添加一个如下参数来完成此操作:

    {
    "_id"    : "1234567890",
    "area"   : "Zone 63",
    "last_state" : "Cloudy",
    "recent_indices" : [
            21,
            18,
            33,
            ...
            38
            41
      ],
    
    "Report_stats" : [
     {
            "date_hour" : "2017-01-01 01",
            "count"     : 31
         },
     {
            "date_hour" : "2017-01-01 02",
            "count"     : 20
         },
            ...
         {
            "date_hour" : "2018-08-26 13",
            "count"     : 3
         }     
      ]
    }
    
    {
     'datetime' : '2018-08-26 13:48:11.677635',
     'areas'    : 'Zone 3; Zone 45; Zone 63',
     'status'   : 'Clear',
     'index'    : '33'
     }
    
    update_one( {'_id':1}, {$set:{}}, upsert=True )
    
    如果要更新多个字段,只需设置更新的文档:

    {
        name: 'Kanika',
        age: 19
    },
    //set document
    {
        name: 'Andy',
        age: 30
    }
    
    如果有帮助,请尝试查看:


    谢谢,Kanika

    到目前为止,我找到的最佳解决方案是:

    if mycollection.find_one({'area': 'zone 45', 'Report_stats.date_hour': '2018-08-26 13'}):
        mycollection.update_one({'area': 'zone 45', 'Report_stats.date_hour': '2018-08-26 13'},
                                        {
                                        '$inc': {
                                            'Report_stats.$.count': 1
                                            },
                                        '$set': {
                                            'last_state': 'Clear'
                                            },
                                        '$push': {
                                            'recent_indices': 33,
                                            }
                                        },
                         )
    else:
        mycollection.update_one({'area': 'zone 45'},
                                         {
                                         '$set': {
                                             'last_state': 'Clear'
                                             },
                                         '$push': {
                                             'recent_indices': 33,
                                             'Report_stats':{'date_hour':'2018-08-26 13', 'count':1}
                                             }
                                         },
                                         upsert = True
                         )
    
    然而,它仍然在根据一个请求执行两次一个查询来更新一个文档,这不是很令人满意


    有更好的建议吗?

    如果我从您的上述回复中发现,如果您的文档中存在
    Report\u stats.date\u hour,那么您可以增加计数器,或者只需推送一个新文档。

    我相信我们可以使用$cond或$switch来实现。你能看一下吗

    同时,我正在尝试为您编写整个查询,让我们看看它是否有效


    谢谢,卡尼卡

    显然,我知道upsert是什么。正如我所指出的,我已经尝试了你的建议,但问题是文档的结构应该按照我解释的方式进行更新。不过,谢谢您的回复。谢谢,是的,您答对了,但似乎$cond和$switch用于聚合,所以我不确定如何在更新查询中使用它们。有什么我遗漏的吗?您可以使用聚合而不是查找查询,然后您可以使用只更新一个(…),而不是在“如果和其他”中进行。好的,谢谢。我会调查的。然而,如果您有时间像您所说的那样编写查询,那将不胜感激。