每天,我收到一份文件(更新).我想要做的是插入每个尚不存在的项目.
我正在使用Python驱动程序(pymongo).
我目前做的是(伪代码):
for each document in update:
existing_document = collection.find_one(document)
if not existing_document:
document['insertion_date'] = now
else:
document = existing_document
document['last_update_date'] = now
my_collection.save(document)
Run Code Online (Sandbox Code Playgroud)
我的问题是它非常慢(少于100 000条记录需要40分钟,而且我在更新中有数百万条记录).我很确定有内置的东西可以做到这一点,但更新()的文件是mmmhhh ....有点简洁....(http://www.mongodb.org/display/DOCS/Updating)
有人可以建议如何更快地做到这一点?
假设我有一组使用MongoEngine定义的文档:
class Project(Document):
name = StringField(required=True)
client = StringField(required=True)
code = StringField(required=True,unique=True)
created = DateTimeField(required=True,default=datetime.datetime.now)
Run Code Online (Sandbox Code Playgroud)
从历史上看,我可以使用该get_or_create方法执行"插入或更新"类型的操作.例如:
Project.objects().get_or_create(name="Test Project One",
client="Client One",
code="CL1-001")
Run Code Online (Sandbox Code Playgroud)
其中将以下文档添加到集合中:
{
"name": "Test Project One",
"client": "Client One",
"code": "CL1-001",
"created": {
"$date": "2014-07-14T14:00:38.024Z"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这种方法现在已经贬值了建议的替代方法是使用update_one具有upsert=True如下:
Project.objects(code="CL1-002").update_one(set__name="Test Project Two",
set__client="Client One",
upsert=True)
Run Code Online (Sandbox Code Playgroud)
但这导致文档被添加到集合中而没有created字段:
{
"client": "Client One",
"code": "CL1-002",
"name": "Test Project Two"
}
Run Code Online (Sandbox Code Playgroud)
是否有任何方法可以在get_or_create没有竞争条件的情况下使用MongoEngine 复制默认字段行为?
我知道get_or_create现在已经弃用了赞成使用upsert,但是如何update_one返回对象而不是修改对象的数量,如果我不想更新任何东西,我可以只检索一个对象吗?
例如
Model.objects.get_or_create(first_name='John', last_name='Potter', age=40)
# assuming that first_name + last_name + age are enough to uniquiely indentify a person
Run Code Online (Sandbox Code Playgroud)
返回一个Model对象(如果它不存在则为新对象,如果存在,则返回现有对象).使用新方法相当于什么?
Model.objects(first_name='John', last_name='Potter', age=40).update_one(upsert=True)
# returns number of objects (1)
Model.objects(first_name='John', last_name='Potter', age=40).update_one(set__first_name='John', set__last_name='Potter', set__age=40,upsert=True)
# returns number of objects (1)
Run Code Online (Sandbox Code Playgroud)
有没有办法让它返回对象,并使其行为完全像get_or_create?
我在文档中找不到如何做到这一点