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

2024-06-16 14:07:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我不明白pymongo中create_indexensure_index之间的区别。上面写着

you can create an index by calling the ensureIndex()

但是在pymongo中有两个不同的命令^{}^{},create index的文档有:

Unlike create_index(), which attempts to create an index unconditionally, ensure_index() takes advantage of some caching within the driver such that it only attempts to create indexes that might not already exist. When an index is created (or ensured) by PyMongo it is “remembered” for ttl seconds. Repeated calls to ensure_index() within that time limit will be lightweight - they will not attempt to actually create the index.

我是否正确地理解了ensure_index将创建永久索引,或者我需要为此使用create_index


Tags: thetoanindexbythatiscreate
3条回答

请记住,在Mongo 3.x中,ensureIndex是不推荐使用的,应该加以劝阻。

Deprecated since version 3.0.0: db.collection.ensureIndex() is now an alias for db.collection.createIndex().

pymongo中也是如此:

DEPRECATED - Ensures that an index exists on this collection.

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

交互式Shell中的ensureIndex方法和python驱动程序中的ensure_index方法是不同的,尽管使用的是同一个词。python驱动程序中的create_indexensure_index方法都永久地创建索引。

在这种情况下,可能会使用ensure_index和一个合理的TTL,因为我不确定create_index是否会在每次调用时重新创建索引。娱乐通常是不需要的,这可能是一个沉重的行动。但是,即使是python或ruby驱动程序的ensure_index也可能在TTL过期、从其他客户机实例调用或重新启动后重新创建索引。我不确定这件事。

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

我现在演示如何使用术语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

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

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

同一个标识符在这里有不同的含义,我觉得很混乱。

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

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

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

下次使用同一驱动程序实例上同一集合的同一索引调用ensure_index时,ensure_index命令只会再次插入索引,前提是自第一次调用以来TTL秒尚未过去。

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

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

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

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

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

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

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

@andreas jung是对的,因为ensure_index()create_index()的包装,我认为这个短语会引起混淆:

When an index is created (or ensured) by PyMongo it is “remembered” for ttl seconds.

不是索引是临时的或“暂时的”,而是在指定的秒数内,对试图再次创建相同索引的ensure_index()的调用将不会有任何影响,并将在下面调用create_index(),但在“缓存”过期后,调用ensure_index()将再次调用下面的create_index()

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

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

Calls create_index and sets a flag to not do so again for another X minutes. this time can be specified as an option when initializing a Mongo::DB object as options[:cache_time] Any changes to an index will be propogated through regardless of cache time (e.g., a change of index direction)

The parameters and options for this methods are the same as those for Collection#create_index.

Examples:

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

我不是说司机的工作完全一样,只是为了说明他们的解释是更好的一点。

相关问题 更多 >