2

我正在尝试根据本文档将预先汇总的性能指标存储在分片 mongodb 中。

我正在尝试使用这样的 upsert 更新可能存在或不存在的记录中的分钟子文档(self.collection是 pymongo 集合实例):

self.collection.update(query, data, upsert=True)

询问:

{   '_id': u'12345CHA-2RU020130304',
    'metadata': {   'adaptor_id': 'CHA-2RU',
                    'array_serial': 12345,
                    'date': datetime.datetime(2013, 3, 4, 0, 0, tzinfo=<UTC>),
                    'processor_id': 0}
}

数据:

{   'minute': {   '16': {   '45': 1.6693091}}}

问题在于,在这种情况下,“分钟”子文档始终只有最后一个hour: { minute: metric}条目,分钟子文档不会为其他时间创建新条目,它总是覆盖一个条目。

我也尝试过使用 $set 样式的数据输入:

{ '$set': {   'minute': {   '16': {   '45': 1.6693091}}}}

但它最终是一样的。

我究竟做错了什么?

4

2 回答 2

2

我最终设置了这样的字段:

询问:

{   '_id': u'12345CHA-2RU020130304',
    'metadata': {   'adaptor_id': 'CHA-2RU',
                    'array_serial': 12345,
                    'date': datetime.datetime(2013, 3, 4, 0, 0, tzinfo=<UTC>),
                    'processor_id': 0}
}

我正在设置这样的指标:

data = {"$set": {}}

for metric in csv:
  date_utc = metric['date'].astimezone(pytz.utc)
  data["$set"]["minute.%d.%d" % (date_utc.hour,
                                date_utc.minute)] = float(metric['metric'])

它创建这样的数据:

{"$set": {'minute.16.45': 1.6693091,
          'minute.16.46': 1.566343,
          'minute.16.47': 1.22322}}

这样在self.collection.update(query, data, upsert=True)运行时它会更新这些字段。

于 2013-03-19T21:07:45.113 回答
2

在列出的两个示例中,您只是将字段 ( 'minute') 设置为特定值,它是第一次更新时添加的唯一原因是因为字段本身不存在,因此必须创建。

很难确定你在这里拍摄的确切目标,但我认为你可以做的是稍微改变你的模式,这样它'minute'就是一个数组。然后,您可以使用$push添加值,无论它们是否已经存在或者$addToSet您不想重复。

我不得不稍微修改您的文档以使其在 shell 中有效,因此我的_id(和其他一些字段)与您的略有不同,但它仍然应该足够接近以进行说明:

db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty()
{
        "_id" : "u12345CHA-2RU020130304",
        "metadata" : {
                "adaptor_id" : "CHA-2RU",
                "array_serial" : 12345,
                "date" : ISODate("2013-03-18T23:28:50.660Z"),
                "processor_id" : 0
        }
}

现在让我们添加一个minute包含文档数组而不是单个文档的字段:

db.foo.update({'_id': 'u12345CHA-2RU020130304'}, { $addToSet : {'minute': { '16': {'45': 1.6693091}}}})
db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty()
{
        "_id" : "u12345CHA-2RU020130304",
        "metadata" : {
                "adaptor_id" : "CHA-2RU",
                "array_serial" : 12345,
                "date" : ISODate("2013-03-18T23:28:50.660Z"),
                "processor_id" : 0
        },
        "minute" : [
                {
                        "16" : {
                                "45" : 1.6693091
                        }
                }
        ]
}

然后,为了说明添加,添加一个稍微不同的条目(因为我正在使用$addToSet这是添加新字段所必需的:

db.foo.update({'_id': 'u12345CHA-2RU020130304'}, { $addToSet : {'minute': { '17': {'48': 1.6693391}}}})
db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty()
{
        "_id" : "u12345CHA-2RU020130304",
        "metadata" : {
                "adaptor_id" : "CHA-2RU",
                "array_serial" : 12345,
                "date" : ISODate("2013-03-18T23:28:50.660Z"),
                "processor_id" : 0
        },
        "minute" : [
                {
                        "16" : {
                                "45" : 1.6693091
                        }
                },
                {
                        "17" : {
                                "48" : 1.6693391
                        }
                }
        ]
}
于 2013-03-18T23:33:31.890 回答