识别和外推
#index #nosql #mongodb #atlas

检测

语境

在某些情况下,我们需要出于某种原因来识别自己,要么是为了记录环境,甚至是为了在另一个环境中复制这些界面,例如开发,化合物,甚至将它们投入生产。拥有一个识别这些脚本在几种意义上很重要,并且总是很好。

在我的情况下,这是出于文档的目的而出现的,尤其是确定某些数据库集合是否与TTL类型相关,广泛用于自动数据清除。P>>

注意:这里的目的是使用JavaScript使用Mongosh列出ândices,可以提出代码的任何改进!最后,如果您希望直接为其运行,则添加Python脚本。

连接

这里使用的群集是在MongoDB地图集中,如果您没有€测试环境可以创建一个完全免费的aqui群集。

让我们使用mongosh是MongoDB管理的完整接口。我将逐步演示,最后添加所有内容以创建我们的Saãda脚本。同样重要的是要强调,以下命令是在mongodb的5.0处执行的。

mongosh "mongodb+srv://<cluster_uri>/myFirstDatabase" --apiVersion 1 --username <user>

列表数据库

此处重要的是要注意,用于脚本连接 /执行的用户必须具有某些任务的必要特权,例如列表数据库,列表集合和最后的ãndices。在此link中查看有关MongoDB权限的更多信息。

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    print(myDB);
});

列出集合

现在,使用群集的数据库的名称,我们可以添加另一个步骤并列出它们每个集合的名称。请注意,我们不想列出数据库的集合 admin ,也不要 local

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`Coleções no banco de dados ${myDB}:`);
        db.getCollectionNames().forEach(collectionName => {
            print(`- ${collectionName}`);
        });
    }
});

列出

现在,让我们终于列出每个集合的论点:

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`Coleções no banco de dados ${myDB}:`);
        db.getCollectionNames().forEach(collectionName => {
            print(`- ${collectionName}`);
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                print(`  - ${index.name} (${JSON.stringify(index)})`);
            });
        });
    }
});

请注意,对于每个迷来说,我们都有其名称以及构成每个属性的属性。这很重要,不要是这些属性的识别,而是为创建每个属性生成休假。

添加CreateIndex()

让我们稍微修改脚本,以便它命令我们创建其中的每一个:

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`Coleções no banco de dados ${myDB}:`);
        db.getCollectionNames().forEach(collectionName => {
            print(`- ${collectionName}`);
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                print(`  - ${index.name} (${JSON.stringify(index)})`);
                print(`    -- create: db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
            });
        });
    }
});

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`Coleções no banco de dados ${myDB}:`);
        db.getCollectionNames().forEach(collectionName => {
            print(`- ${collectionName}`);
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                if(index.name !== "_id_"){
                    print(`  - ${index.name} (${JSON.stringify(index)})`);
                    print(`    -- create: db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
                }
            });
        });
    }
});

确定属性

好吧,我们在这里到达©©,但是如果我们只想列出TTL属性(该帖子的来源是如何发生的)?

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`Coleções no banco de dados ${myDB}:`);
        db.getCollectionNames().forEach(collectionName => {
            print(`- ${collectionName}`);
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                if(index.name !== "_id_"){
                    if (index.expireAfterSeconds !== undefined) {
                        print(`  - ${index.name} (${JSON.stringify(index)})`);
                        print(`    -- create: db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
                    }
                }
            });
        });
    }
});

关于创建的注释

在我们加入一切之前,只是一个观察。当我们谈论生产环境时,必须对迷人的创建进行精心计划,有一些方法可以对MongoDB产生较小的影响。请参阅此link中的一些建议。

值得记住的是,这篇文章的最终目标是要确定现有的目标,因此我们也有一个脚本。

加入一切

ph,多少!现在,让我们把所有内容放在一起,以便我们的脚本真正起作用:

  • 列出每个数据库的每个集合的所有收藏集的所有(除 _id );
  • 生成创建它们的命令;
  • 最后,只有ttl。

全部

var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`use ${myDB};`);
        db.getCollectionNames().forEach(collectionName => {
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                if (index.expireAfterSeconds !== undefined) {
                        printjson(`db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
                }
            });
        });
    }
});
文件

在这里使其更容易,我们将脚本的遏制放在名为 verifyIndex.js 的文件中,您可以根据需要创建此文件。最后,我们将拥有一个称为 outputIndex.js 的输出文件,这将是带有最终控制的脚本来识别/创建ãndices。

  • 创建 verifyIndex.js 文件
cat << 'index' | tee verifyIndex.js
var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`use ${myDB};`);
        db.getCollectionNames().forEach(collectionName => {
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                if(index.name !== "_id_"){
                    printjson(`db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
                }
            });
        });
    }
});
index
  • 使用 mongosh 加载文件。在这里,我们使用以下部分:
    • -file指示将加载的文件
    • quiet用于输出文件,以包含执行MONOSH的任何记录,作为连接开口等。
    • 最后,输出将写在 outputIndex.js 文件中
mongosh "mongodb+srv://<user>:<password>@<cluster_uri>/test" --file verifyIndex.js --quiet > outputIndex.js

检查 outputIndex.js file 时,我们看到我们有所有命令来创建每个数据库中每个集合中的所有内容。

只有TTL

通过此修改,文件的文件仅包含用于创建TTL类型的命令:

saãada用于ttl ondices文件
cat << 'index' | tee verifyIndex.js
var myDBs = db.adminCommand({ listDatabases: 1 }).databases.map(db => db.name);
myDBs.forEach(myDB => {
    if (myDB !== 'admin' && myDB !== 'local') {
        db = db.getSiblingDB(myDB);
        print(`use ${myDB};`);
        db.getCollectionNames().forEach(collectionName => {
            let indexes = db.getCollection(collectionName).getIndexes();
            indexes.forEach(index => {
                if (index.expireAfterSeconds !== undefined) {
                        printjson(`db.getCollection("${collectionName}").createIndex(${JSON.stringify(index.key)}, ${JSON.stringify(index)});`)
                }
            });
        });
    }
});
index

如果您愿意,请使用Python!

from pymongo import MongoClient

def get_databases(conn):
    dbs = conn.admin.command({"listDatabases": 1})
    return dbs["databases"]

def get_collections(conn, db_name):
    db = conn[db_name]
    return db.list_collection_names()

def get_indexes(conn, db_name, collection):
    db = conn[db_name]
    coll = db[collection]
    indexes = coll.index_information()
    return indexes

client = MongoClient("mongodb+srv://<user>:<password>@<cluster_uri>/?retryWrites=true&w=majority")

databases = get_databases(client)
for database in databases:
    with open("outputIndex1.js", "a") as output_index:
        if database["name"] != "local" and database["name"] != "admin" and database["name"] != "config":
            print("Database: {0}".format(database["name"]))
            collections = get_collections(client, database["name"])
            for collection in collections:
                print("  - Coleção: {0}".format(collection))
                indexes = get_indexes(client, database["name"], collection)
                for index in indexes.items():
                    if index[0] != "_id_":
                        keys = { key: value for key, value in index[1]["key"]}
                        options = {option: value for option, value in index[1].items() if option not in ('v', 'key')}
                        options.update({"name": index[0]})
                        output_index.write("db.{0}.createIndex({1},{2})\n".format(collection, keys, options))
                        print("    - Índice: {0}".format(index[0]))