Python mongodb中高效的集合查找和索引创建

Python mongodb中高效的集合查找和索引创建,python,mongodb,pymongo,Python,Mongodb,Pymongo,我的数据库中有大量数据,每秒多达1000个文档。当我收到每一个文档时,我会根据文档中的一个字段有效地检查是否已经存在该类型文档的集合,如果没有,我会在该集合上创建一些索引。基本上,我想知道在空集合上创建索引需要多长时间,以及是否有更快的方法来检查是否存在具有指定名称的集合 def insert_new_doc(json_doc): collection_name = json_doc["collection_name"] coll = tlm_db_connection[collecti

我的数据库中有大量数据,每秒多达1000个文档。当我收到每一个文档时,我会根据文档中的一个字段有效地检查是否已经存在该类型文档的集合,如果没有,我会在该集合上创建一些索引。基本上,我想知道在空集合上创建索引需要多长时间,以及是否有更快的方法来检查是否存在具有指定名称的集合

def insert_new_doc(json_doc):
  collection_name = json_doc["collection_name"]
  coll = tlm_db_connection[collection_name]

  # create indexes in background if the collection doesn't exist
  if tlm_db_connection.system.namespaces.find( { name : collection_name } ) == None:
      coll.ensure_index([('time_stamp', pymongo.DESCENDING)], background = True)
      coll.ensure_index([('raw_value', pymongo.DESCENDING)], background = True)
      coll.ensure_index([('time_stamp', pymongo.DESCENDING), ('raw_value', pymongo.DESCENDING)], background = True)

  coll.insert(json_doc)

这就是我的功能。如果我确保将_index设置为background=True,您知道它会阻止调用该函数的线程多长时间吗?

在空集合上创建新索引相当快,您可以通过运行以下测试来测量它

function howLong(){

    var t0 = new Date().valueOf();
    db.myCollection.ensureIndex({name: 1});
    var t1 = new Date().valueOf();

    return t1 - t0;
}
EnsureIndex将阻塞,直到创建索引为止。我的旧笔记本电脑上写着0:)

同样的技术也可以用于在mongoshell中获得索引的大约“背景”创建时间

后台索引操作在后台运行,以便其他 创建索引时可以运行数据库操作。但是, 您正在创建索引的mongo shell会话或连接 将阻止,直到索引生成完成

如果您足够早地调用ensureIndex,它将非常快,即在我的机器上索引100000个项目(按用户集合名称索引)大约需要350毫秒

随后对ensureIndex的调用(创建之后)将立即退出(带有适当的消息),但如果可以,我不会这样做。(即数据库由我控制,不与其他人共享)我将使用专用线程创建索引

由于您的集合将快速增长,并且您将创建一个索引,因此请确保它适合RAM,以便在插入时对数据进行预聚合

关于检查集合的存在性,假设您的应用程序是唯一一个写入db的应用程序,您可以在启动时列出所有集合,并将这些信息保存在内存中


10gen实验室有一个有趣的项目似乎解决了类似的问题(尽管是java代码),可能值得一看

他们根本不应该阻塞,只需要接收服务器的确认即可。因为一些愚蠢的原因我记不起来了。pymongo驱动程序不是aync,所以从技术上讲,它会阻塞所有数据块,但不会在索引构建期间阻塞。您在服务器上使用哪个MongoDB版本?好的,这很有意义。我正在运行2.6.7。那么你在问什么?这需要多长时间?或者它“阻塞”了多长时间?这里可能存在的歧义是“调用是否等待后台构建完成”,这是一个更简洁的问题。顺便说一句,那里的第一个索引语句被第三个索引冗余了。这样做只会浪费空间,因为可以使用第一个索引的查询也可以使用第三个索引。是的,我看到它有点模棱两可。问题是开始索引创建的实际调用需要多长时间。以数据传入的速度和调用此函数的频率来看,我担心这会花费太长时间并从队列中删除消息,因此我希望尽快完成。感谢冗余说明,我已更正了代码。非常感谢您的回复。你知道如果我在后台建立索引会不会慢一些吗?我本来打算这么做的,但我担心有多个实例,而且我的类在实例之间不能同步更新。你知道这些问题吗?