Pymongo / MongoDB:创build索引或确保索引?

我不明白ensure_indexcreate_indexensure_index的区别。 在MongoDB索引页面上 ,它说

你可以通过调用ensureIndex()来创build索引

但是在pymongo中有两个不同的命令create_indexensure_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_indexensure_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.jssearchfunction ensureIndex

2)它创build一个索引,如果它不在'驱动程序caching'

在这里使用相同的标识符具有不同的含义,这使我感到困惑。

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

他们不告诉数据库关于这个caching。

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

下一次在同一个驱动程序实例中调用与同一个集合相同索引的ensure_index时,如果自第一次调用以来尚未传递TTL秒,那么ensure_index命令将只会再次插入索引。

如果你调用create_index ,索引总是被插入,不pipe第一次调用多less时间,当然如果这是第一次调用。

这是python驱动程序,在文件collection.pysearchdef ensure_index

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

和ruby驱动程序一样,在文件collection.rbsearchdef 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每个查询或集合更新:)