Pymongo / MongoDB:创建索引还是确保索引?

时间:2011-05-06 14:12:48

标签: python mongodb pymongo

我不明白pymongo中create_indexensure_index之间的区别。在MongoDB indexes page上,它说

  

你可以通过调用来创建一个索引   ensureIndex()

但是在pymongo中有两个不同的命令create_indexensure_index,而create index的文档有:

  

与create_index()不同,后者尝试   无条件地创建索引   ensure_index()利用了一些优势   在驱动程序内缓存它   只尝试创建索引   可能还不存在。当一个索引   由PyMongo创建(或确保)它   是“记住”ttl秒。   重复调用ensure_index()   在那个时间限制内   轻量级 - 他们不会尝试   实际创建索引。

我是否理解ensure_index会创建永久索引,或者我需要使用create_index吗?

6 个答案:

答案 0 :(得分:39)

@ andreas-jung是正确的,因为ensure_index()create_index()的包装,我认为这句话引起了混淆:

  

创建(或确保)索引时   通过PyMongo它被ttl“记住”   秒。

指数不是暂时的或“短暂的”,会发生的是,在指定的秒数内,调用ensure_index()尝试再次创建相同的索引将如果有任何效果,会在下面调用create_index(),但在“缓存”过期后,对ensure_index() 的调用将再次调用{{1在下面。

我完全理解你的困惑,因为坦率地说,PyMongo的文档并没有很好地解释它是如何工作的,但是如果你转到Ruby docs,解释会更清楚一些:

  
      
  • (String)ensure_index(spec,opts = {})
  •   
     

调用create_index并将标志设置为   再过一次X分钟不再这样做了。   这个时间可以指定为   初始化Mongo :: DB时的选项   object as options [:cache_time] Any   对索引的更改将被传播   通过不管缓存时间   (例如,改变索引方向)

     

此参数和选项   方法与那些方法相同   收集#CREATE_INDEX。

     

示例:

     

create_index()

     

Call sequence:

     

Time t: @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and sets the 5 minute cache

     

Time t+2min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- doesn't do anything

     

Time t+3min : @posts.ensure_index([['something_else', Mongo::ASCENDING]) -- calls create_index and sets 5 minute cache

我并没有声称司机工作完全相同,只是为了说明目的,他们的解释是更好的恕我直言。

答案 1 :(得分:14)

请注意,在Mongo 3.x中ensureIndex已被弃用,不应该被劝阻。

  

自3.0.0版开始不推荐使用:db.collection.ensureIndex()现在是db.collection.createIndex()的别名。

同样在pymongo

  

DEPRECATED - 确保此集合上存在索引。

这意味着您应该始终使用create_index

答案 2 :(得分:9)

交互式Shell中的ensureIndex方法和python驱动程序中的ensure_index是不同的东西,尽管使用了相同的单词。来自python驱动程序的create_indexensure_index方法都会永久地创建索引。

在这种情况下,也许有人会使用ensure_index合理的TTL,因为我不确定每次调用它时create_index是否会重新创建索引。通常不需要娱乐,这可能是一个繁重的操作。但是,即使ensure_index(python或ruby驱动程序)也可能在TTL过期或从其他客户端实例或重新启动后调用它时重新创建索引。我不确定这一点。

如果索引已经存在,可能更好的方法是首先使用方法index_information()进行检查。如果它已经存在,则不会再创建它。

我现在正在演示术语ensure_index(或ensureIndex)如何用于两种不同的含义:

1)如果数据库中尚不存在索引,则会创建索引

这就是 Interactive Shell 方法ensureIndex()所做的:

http://www.mongodb.org/display/DOCS/Indexes#Indexes-Basics

Node.JS MongoDB Driver也是这样的:

https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js

(在文件function ensureIndex中搜索collection.js。)

2)如果它不在“驱动程序缓存”中,它会创建一个索引

这里使用的标识符不同,我觉得这很复杂。

python和ruby驱动程序在内存中存储有关最近创建的索引的信息,并将这种行为称为“缓存”。

他们没有告诉数据库有关此缓存的信息。

这种机制的结果是,如果您第一次使用TTL值(生存时间)调用create_indexensure_index,则驱动程序将在数据库中插入索引并将记住这个插入并将TTL信息存储在内存中。这里缓存的是时间和索引。

下次在同一驱动程序实例上使用相同集合的相同索引调用ensure_index时,ensure_index命令将仅再次插入索引,如果自TTL秒起尚未通过TTL秒第一次打电话。

如果你拨打create_index,无论自第一次通话以来经过了多长时间,都将始终插入索引,当然,如果这是第一次通话,也会插入索引。

这是python驱动程序,在文件def ensure_index中搜索collection.py

https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py

红宝石驱动程序,在文件def ensure_index中搜索collection.rb

https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/collection.rb

(请注意,不同的客户端实例不知道其他客户端的缓存,此信息仅保留在内存中,而且是每个实例。如果重新启动客户端应用程序,新实例不知道旧的“缓存”索引插入。其他客户也不知道,他们不会互相告诉。)

当python驱动程序或ruby驱动程序插入已存在的索引时,我还无法完全理解db中会发生什么。我怀疑他们在这种情况下什么都不做,这更有意义,也会匹配Interactive Shell和JS驱动程序的行为。

答案 3 :(得分:3)

所有索引都是永久性的。 ensure_index()只是create_index()的一个小包装。

“”” ensureIndex()函数仅在索引不存在时才创建索引。 “”“

没有像瞬态索引或临时索引那样的东西。

答案 4 :(得分:0)

您应该使用 create_index 而不是因为他们在答案和文档本身中所说的 ensureIndex() 已弃用,https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#recreating-an-existing-index 这就是您应该使用 create_index 的原因 ,正如他们所说

“如果您为已经存在的索引调用 db.collection.createIndex(),MongoDB 不会重新创建索引。”

答案 5 :(得分:-1)

我建议创建元类和ORM。 从元类 init 调用init_schema方法来初始化计数器,模式,键等。 这样就可以防止在每次查询或集合更新时调用ensure_index:)