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

时间:2018-08-26 15:35:05

标签: python mongodb mongodb-query pymongo

我有一个包含以下文档的收藏集:

Rating

应该根据一些在线实时报告进行更新 并假设每个报告如下所示:

{
"_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
     }     
  ]
}

现在我必须以以下方式更新集合:

  1. 每次在报告上显示一个新的“区域”(例如1025区域)时,都会添加一个新文档来保存相关数据
  2. 新的“索引”添加到列表“ recent_indices”,而“ last_state”更新为“状态”
  3. 根据“日期时间”是什么,相应的“ Report_stats.count”将增加1或插入一个新的“ Report_stats”文档(具有小时分辨率的“ datetime”,其“ count”为1)。

分别进行每个更新的方式在某种程度上很明显,问题是:如何在一个更新/更新任务中同时完成所有这些工作?

我尝试通过pyMongo使用{ 'datetime' : '2018-08-26 13:48:11.677635', 'areas' : 'Zone 3; Zone 45; Zone 63', 'status' : 'Clear', 'index' : '33' } update_one(以及find_one_and_updateupdate),但是(至少对我来说)无法解决问题。

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

您能帮我怎么做,或者(因为正在收集大量数据,因此应该进行处理)建议使用低成本的替代方法?

谢谢!

3 个答案:

答案 0 :(得分:0)

我不确定我是否理解您的问题,但是不确定您的问题是否围绕upsert进行,即更新该问题或添加记​​录(如果该记录不存在)。 您可以通过添加一个这样的参数来做到这一点:

update_one( {'_id':1}, {$set:{}}, upsert=True )

如果您要更新多个字段,则可以像设置更新的文档一样简单地完成此操作:

{
    name: 'Kanika',
    age: 19
},
//set document
{
    name: 'Andy',
    age: 30
}

请尝试查看:https://docs.mongodb.com/manual/reference/method/db.collection.update/,如果有帮助。

谢谢卡妮卡

答案 1 :(得分:0)

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

d = (df
 .assign(year_month=df['Date'].dt.strftime('%Y/%m'))
 .groupby('year_month')['value']
 .apply(list)
 .to_dict()
)

df = pd.concat([pd.Series(v, name=k) 
                for k, v in d.iteritems()], axis=1)[sorted(d)]

>>> df
   2017/01  2017/04  2017/07  2018/04  2018/07
0        5        6       15       50       11
1        5       12      NaN      NaN      NaN

但是,它仍然要执行两次查询以根据一个请求更新一个文档,但这并不令人满意。

还有更好的建议吗?

答案 2 :(得分:0)

如果我从您的上述答复中发现,如果 Report_stats.date_hour exists in your document, then you increment the counter or else you just push a new document.

我相信我们可以使用 $ cond或$ switch 做到这一点。可以请你看看。

https://docs.mongodb.com/manual/reference/operator/aggregation/cond/#exp._S_cond

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

谢谢卡妮卡