我不明白pymongo中create_index
和ensure_index
之间的区别。在MongoDB indexes page上,它说
你可以通过调用来创建一个索引
ensureIndex()
但是在pymongo中有两个不同的命令create_index
和ensure_index
,而create index的文档有:
与create_index()不同,后者尝试 无条件地创建索引 ensure_index()利用了一些优势 在驱动程序内缓存它 只尝试创建索引 可能还不存在。当一个索引 由PyMongo创建(或确保)它 是“记住”ttl秒。 重复调用ensure_index() 在那个时间限制内 轻量级 - 他们不会尝试 实际创建索引。
我是否理解ensure_index
会创建永久索引,或者我需要使用create_index
吗?
答案 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_index
和ensure_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_index
或ensure_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:)