Mongodb 向上插入pymongo和一个自定义id字段

Mongodb 向上插入pymongo和一个自定义id字段,mongodb,pymongo,Mongodb,Pymongo,我正试图根据以下内容将预先聚合的性能指标存储在分片的mongodb中 我正在尝试更新记录中的分钟子文档,该记录可能存在,也可能不存在这样的upsert。集合是pymongo集合实例: self.collection.update(query, data, upsert=True) 查询: { '_id': u'12345CHA-2RU020130304', 'metadata': { 'adaptor_id': 'CHA-2RU', 'a

我正试图根据以下内容将预先聚合的性能指标存储在分片的mongodb中

我正在尝试更新记录中的分钟子文档,该记录可能存在,也可能不存在这样的upsert。集合是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}
}
{   '_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:metric}条目,分钟子文档不会为其他小时创建新条目,它总是覆盖一个条目

我还尝试了$set样式的数据输入:

{ '$set': {   'minute': {   '16': {   '45': 1.6693091}}}}
但结果是一样的


我做错了什么?

在列出的两个示例中,您只是简单地将字段“分钟”设置为特定值,第一次更新时它是一个加法的唯一原因是因为字段本身不存在,因此必须创建

很难确定您在这里拍摄的是什么,但我认为您可以做的是稍微改变您的模式,使“分钟”成为一个数组。然后,您可以使用添加值,而不管它们是否已经存在,或者您是否不希望重复

我不得不稍微修改一下您的文档,使其在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
        }
}
现在,让我们添加一个分钟字段,其中包含文档数组,而不是单个文档:

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

在列出的两个示例中,您只是将字段“分钟”设置为特定值,第一次更新时它是一个加法的唯一原因是因为字段本身不存在,因此必须创建该字段

很难确定您在这里拍摄的是什么,但我认为您可以做的是稍微改变您的模式,使“分钟”成为一个数组。然后,您可以使用添加值,而不管它们是否已经存在,或者您是否不希望重复

我不得不稍微修改一下您的文档,使其在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
        }
}
现在,让我们添加一个分钟字段,其中包含文档数组,而不是单个文档:

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

我最终设置了如下字段:

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}}
查询:

{   '_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}
}
{   '_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.updatequery,data,upsert=True时,它会更新这些字段。

我最后设置了如下字段:

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}}
查询:

{   '_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}
}
{   '_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.updatequery,data,upsert=True时,它会更新这些字段。

将小时:分钟存储为数组中的项目是否会否定我在上面提到的链接中列出的查找好处?另外,您在_id中包含的“u”并不一定存在,它是一个表示unicode的python打印工件。谢谢,我会考虑一下。将小时:分钟存储为数组中的项目是否会否定我在上面提到的链接中列出的seek好处?另外,您在_id中包含的“u”并不一定存在,它是一个表示unicode的python打印工件。谢谢,我会考虑的。