Pymongo / MongoDB:创build索引或确保索引?
我不明白ensure_index
中create_index
和ensure_index
的区别。 在MongoDB索引页面上 ,它说
你可以通过调用
ensureIndex()
来创build索引
但是在pymongo中有两个不同的命令create_index
和ensure_index
,并且create index的文档有:
与create_index()不同,它试图无条件地创build一个索引,ensure_index()利用驱动程序中的一些caching,只尝试创build可能不存在的索引。 当PyMongo创build(或确保)索引时,“记住”ttl秒。 在此限制内重复调用ensure_index()将是轻量级的 – 它们不会尝试实际创build索引。
我正确的理解, ensure_index
将创build一个永久性的索引,还是我需要使用create_index
呢?
请记住,在Mongo 3.x中, ensureIndex已被弃用,应该劝阻。
自3.0.0版以来不推荐使用:db.collection.ensureIndex()现在是db.collection.createIndex()的别名。
pymongo也一样 :
已弃用 – 确保此collections夹上存在索引。
这意味着你应该总是使用create_index
。
@andreas-jung是正确的,因为ensure_index()
是create_index()
一个包装器,我认为这个混淆出现在这个短语中:
当PyMongo创build(或确保)索引时,“记住”ttl秒。
这不是索引是临时的或“暂时的”,会发生什么情况是,在指定的秒数内,调用ensure_index()
试图再次创build相同的索引不会有任何效果,并且不会调用下面的create_index()
但在“caching”过期后,对ensure_index()
调用将再次调用下方的create_index()
。
我完全理解你的困惑,因为坦率地说,PyMongo的文档不能很好地解释它是如何工作的,但是如果你转向Ruby文档 ,解释会更清晰一些:
- (String)ensure_index(spec,opts = {})
调用create_index并设置一个标志,在另一个X分钟内不再这样做。 这个时候可以被指定为一个选项,当一个Mongo :: DB对象初始化为options [:cache_time]时,无论caching时间如何,索引都将被传播(例如,索引方向的改变)
这个方法的参数和选项与Collection#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
Time t+10min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and resets the 5 minute counter
我没有声称司机工作完全一样,只是为了说明的目的,他们的解释是一个更好的恕我直言。
Interactive Shell中的ensureIndex
方法和python驱动程序中的ensure_index
是不同的东西,尽pipe使用了相同的单词。 python驱动程序中的create_index
和ensure_index
方法都会永久创build一个索引。
在这种情况下,可能会使用ensure_index
和合理的TTL,因为我不确定create_index
会在每次调用它时重新创build索引。 娱乐通常是不期望的,这可能是一个沉重的操作。 但是,甚至当这个TTL过期的时候,或者当你从一个不同的客户端实例中调用它时,或者在重新启动之后,甚至可以重新创build索引(python或者ruby驱动程序)的ensure_index
。 我不确定这一点。
如果索引已经存在,也许更好的办法是先使用index_information()
方法检查。 如果它已经存在,你不会再创build它。
现在我正在演示如何使用术语ensure_index
(或ensureIndex
)以及两个不同的含义:
1)如果它还不存在于数据库中,它将创build一个索引
这就是交互式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
(在文件collection.js
searchfunction ensureIndex
)
2)它创build一个索引,如果它不在'驱动程序caching'
在这里使用相同的标识符具有不同的含义,这使我感到困惑。
python和ruby驱动程序将关于最近创build的索引的信息存储在内存中,并将这种行为称为“caching”。
他们不告诉数据库关于这个caching。
这个机制的结果是,如果你第一次调用create_index
或ensure_index
的TTL值(生存时间),那么驱动程序将把索引插入到数据库中,并记住这个插入,并且将TTL信息存储在内存中。 这里caching的是时间和索引。
下一次在同一个驱动程序实例中调用与同一个集合相同索引的ensure_index
时,如果自第一次调用以来尚未传递TTL秒,那么ensure_index
命令将只会再次插入索引。
如果你调用create_index
,索引总是被插入,不pipe第一次调用多less时间,当然如果这是第一次调用。
这是python驱动程序,在文件collection.py
searchdef ensure_index
:
https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py
和ruby驱动程序一样,在文件collection.rb
searchdef ensure_index
:
https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/collection.rb
(请注意,不同的客户端实例不知道其他客户端的caching,这些信息只保存在内存中,并且是每个实例。如果重新启动客户端应用程序,新实例不知道旧的“caching”索引插入。也有其他客户不知道,他们不相互告知。)
我还不能完全理解,在数据库中发生了什么,当python驱动程序或ruby驱动程序插入已经存在的索引。 我会怀疑他们在这种情况下什么都不做,这更有意义,也将匹配Interactive Shell
和JS驱动程序的行为。
所有指标都是永久性的 ensure_index()只是create_index()的一个小包装。
“”“ensureIndex()函数只在索引不存在时才创build。”“”
没有什么像临时索引或临时索引。
我会build议创build元类和ORM。 从元类初始化调用init_schema方法来初始化计数器,模式,关键等。这样你可以防止调用ensure_index每个查询或集合更新:)