在mongoDB中插入或忽略多个文档

时间:2012-04-30 18:16:31

标签: mongodb pymongo mongodb-query

我有一个集合,其中我的所有文档都至少有这两个字段,比如nameurl(其中url是唯一的,所以我在其上设置了一个唯一索引)。现在,如果我尝试插入带有重复url的文档,它将发出错误并暂停程序。我不想要这种行为,但我需要像mysql的{​​{1}}这样的东西,以便mongoDB不应该插入带有重复insert or ignore的文档并继续下一个文档。

是否有一些参数我可以传递给url命令来实现这种行为?我通常使用insert执行一批插入:

pymongo

此处collection.insert(document_array) 是一个集合,collection是一个文档数组。

那么我是否可以通过某种方式为多文档插入实现document_array功能?

7 个答案:

答案 0 :(得分:13)

调用insert()时设置continue_on_error标志。注意PyMongo驱动程序2.1和服务器版本1.9.1是必需的:

  

continue_on_error(可选):如果为True,则数据库不会停止   如果一个失败(例如由于重复的ID),则处理批量插入。   这使得批量插入的行为类似于一系列单个插入,   如果任何插入失败,则会设置lastError,而不仅仅是最后一个   一。如果发生多个错误,则仅报告最新错误   by error()。

答案 1 :(得分:11)

试试这个:

try:
    coll.insert(
        doc_or_docs=doc_array,
        continue_on_error=True)
except pymongo.errors.DuplicateKeyError:
    pass

如果插入中发生错误(例如尝试为唯一索引插入重复值),插入操作仍会抛出异常,但它不会影响数组中的其他项。然后您可以吞下错误,如上所示。

答案 2 :(得分:11)

使用insert_many(),并设置ordered = False。

这将确保尝试所有写入操作,即使存在错误: http://api.mongodb.org/python/current/api/pymongo/collection.html#pymongo.collection.Collection.insert_many

答案 3 :(得分:0)

为什么不在.insert()块内调用try: ... except:,如果插入失败则继续?

此外,您还可以使用update()标记进行常规upsert调用。详情请见http://www.mongodb.org/display/DOCS/Updating#Updating-update%28%29

答案 4 :(得分:0)

如果你的python脚本中已经有你的文档数组,那么为什么不通过遍历它们来插入它们,而只是捕获由于唯一索引而导致插入失败的文档?

for doc in docs:
  try:
    collection.insert(doc)
  except pymongo.errors.DuplicateKeyError:
    print 'Duplicate url %s' % doc

其中collection是从连接/数据库实例创建的集合的实例,docs是您当前要传递到的插入的字典(文档)数组。

您还可以决定如何处理违反except块中唯一索引的重复键。

答案 5 :(得分:-2)

强烈建议使用upsert

  stat.update({'location': d['user']['location']}, \
       {'$inc': {'count': 1}},upsert = True, safe = True)

此处stat是集合,如果访问者位置已经存在于集合中,count增加了一个,则count设置为1

以下是文档http://www.mongodb.org/display/DOCS/Updating#Updating-UpsertswithModifiers

的链接

答案 6 :(得分:-2)

我在做什么:

  1. 生成我想插入的MongoDB ID数组(在我的情况下为某些值的哈希值)
  2. 删除现有ID(我使用的是Redis队列bcoz性能,但您可以查询mongo)
  3. 插入已清理的数据!
  4. Redis非常适合您,您可以根据需要使用Memcached或Mysql Memory