56

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

您可以通过调用 ensureIndex()

但是在 pymongo 中有两个不同的命令create_indexensure_index,创建索引的文档有:

与尝试无条件创建索引的 create_index() 不同,ensure_index() 利用驱动程序中的一些缓存,使其仅尝试创建可能不存在的索引。当 PyMongo 创建(或确保)索引时,它会被“记住” ttl 秒。在该时间限制内重复调用 ensure_index() 将是轻量级的——它们不会尝试实际创建索引。

我是否理解这ensure_index将创建一个永久索引,还是我需要为此使用create_index

4

6 回答 6

40

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

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

并不是索引是临时的或“暂时的”,而是在指定的秒数内,ensure_index()再次尝试创建相同索引的调用不会产生任何影响,也不会在下面调用create_index(),而是在那之后“缓存”过期,一个调用ensure_index() 在下面再次调用create_index()

我完全理解你的困惑,因为坦率地说 PyMongo 的文档在解释它是如何工作的方面做得不是很好,但是如果你去Ruby 文档,解释会更清楚一点:

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

调用 create_index 并设置一个标志以在 X 分钟内不再这样做。在将 Mongo::DB 对象初始化为 options[:cache_time] 时,可以将这个时间指定为一个选项

此方法的参数和选项与 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

我并不是说驱动程序的工作方式完全相同,只是为了说明目的,恕我直言,他们的解释要好一些。

于 2011-05-06T16:35:37.933 回答
21

请记住,在 Mongo 3.x 中,ensureIndex已被弃用,应该不鼓励使用。

自 3.0.0 版起已弃用:db.collection.ensureIndex() 现在是 db.collection.createIndex() 的别名。

pymongo中也是如此:

已弃用 - 确保此集合上存在索引。

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

于 2015-05-19T00:38:36.107 回答
10

ensureIndexInteractive Shell 和python 驱动程序中的方法ensure_index是不同的东西,尽管使用的是同一个词。create_indexpython 驱动程序中的and方法都ensure_index永久创建索引。

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

也许更好的可能性是首先使用方法检查index_information()索引是否已经存在。如果它已经存在,您将不会再次创建它。

我现在正在演示如何以 2 个不同的含义使用术语ensure_index(或):ensureIndex

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

这就是交互式 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​​ 驱动程序将有关最近创建的索引的信息存储在内存中,他们称这种行为为“缓存”。

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

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

下次您ensure_index在同一驱动程序实例上使用同一集合的相同索引调用ensure_index时,如果自第一次调用以来尚未经过 TTL 秒,则该命令只会再次插入索引。

如果你调用create_index,索引将始终被插入,无论自第一次调用以来经过了多少时间,当然如果这是第一次调用也是如此。

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

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

和 ruby​​ 驱动程序,def ensure_index在文件中搜索collection.rb

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

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

我还不能完全理解,当 python 驱动程序或 ruby​​ 驱动程序插入一个已经存在的索引时,数据库中会发生什么。我怀疑他们在这种情况下什么都不做,这更有意义,并且也与Interactive ShellJS 驱动程序的行为相匹配。

于 2012-05-11T13:35:29.770 回答
3

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

""" ensureIndex() 函数仅在索引不存在时创建索引。"""

没有像临时索引或临时索引这样的东西。

于 2011-05-06T14:20:55.300 回答
0

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

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

于 2021-02-01T19:02:01.117 回答
-1

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

于 2013-02-03T18:45:26.183 回答