¿Cómo se cambia el nombre de una base de datos MongoDB?

484

Hay un error tipográfico en el nombre de mi base de datos MongoDB y estoy buscando cambiar el nombre de la base de datos.

Puedo copiar y eliminar así ...

db.copyDatabase('old_name', 'new_name');
use old_name
db.dropDatabase();

¿Hay un comando para cambiar el nombre de una base de datos?

Brian Hempel
fuente
desde mongo 4.2 incluso copyDatabasetambién está en desuso
Sumit Ramteke

Respuestas:

208

No, no lo hay. Ver https://jira.mongodb.org/browse/SERVER-701

Desafortunadamente, esta no es una característica simple para implementar debido a la forma en que los metadatos de la base de datos se almacenan en el motor de almacenamiento original (predeterminado). En los archivos MMAPv1, el espacio de nombres (por ejemplo: dbName.collection) que describe cada colección e índice incluye el nombre de la base de datos, por lo que para cambiar el nombre de un conjunto de archivos de base de datos, cada cadena de espacio de nombres tendría que reescribirse. Esto impacta:

  • el archivo .ns
  • cada archivo numerado para la colección
  • el espacio de nombres para cada índice
  • nombres únicos internos de cada colección e índice
  • contenido de system.namespaces y system.indexes (o sus equivalentes en el futuro)
  • otros lugares me pueden estar perdiendo

Esto es solo para lograr un cambio de nombre de una única base de datos en una instancia de mongod independiente . Para los conjuntos de réplicas, lo anterior debería hacerse en cada nodo de réplica, además, en cada nodo, cada entrada de oplog que haga referencia a esta base de datos debería invalidarse o reescribirse de alguna manera, y luego, si es un clúster fragmentado, también es necesario agregar estos cambia a cada fragmento si el DB está fragmentado, además los servidores de configuración tienen todos los metadatos del fragmento en términos de espacios de nombres con sus nombres completos.

No habría absolutamente ninguna manera de hacer esto en un sistema en vivo.

Para hacerlo sin conexión, sería necesario volver a escribir cada archivo de base de datos para acomodar el nuevo nombre, y en ese punto sería tan lento como el comando actual "copydb" ...

pingw33n
fuente
44
Ese boleto ha estado abierto por mucho tiempo. He agregado mi voto menos que importante a la lista ya larga.
DJ van Wyk
44
Por la forma en que construyeron el DB y lo explicaron, el cambio de nombre parece imposible: podría tomar una arquitectura completamente nueva. Parece un gran descuido, pero todo es justo en el amor, la guerra y el desarrollo de software.
serraosays
Entonces, ¿MongoDB debería tener un comando que llame a dos funciones, copiar y soltar? No veo una gran razón para tener este comando único. Pero podría ser bueno para algunos.
TamusJRoyce
Cuando nombra la base de datos para empezar, DEBERÍA ser un alias para un nombre interno que Mongo genera (utilizando una convención de nomenclatura globalmente única). De esta manera, cambiar el nombre de una base de datos es tan simple como cambiar ese alias y propagarlo a todos los nodos del clúster. Yo digo DEBERÍA. Este no es el caso.
Lonnie Best el
396

Podrías hacer esto:

db.copyDatabase("db_to_rename","db_renamed","localhost")
use db_to_rename
db.dropDatabase();

Nota editorial: este es el mismo enfoque utilizado en la pregunta en sí, pero ha demostrado ser útil para otros independientemente.

bzmw
fuente
38
El tercer argumento se puede omitir realmente y, por defecto, será el mismo servidor.
Haakon
15
Tenga en cuenta que esto no funciona cuando db_to_rename y db_renamed solo difieren en el caso. Tienes que usar una base de datos temporal en esa situación. (Me acabo de encontrar con esto :)
Sebastiaan M
71
¿Cómo es esto diferente de la solución proporcionada por el OP?
Salvador Dali
55
esto es lo mismo que la Pregunta real, con la única diferencia de ser el tercer argumento en el copyDatabasemétodo
Gurbakhshish Singh
2
Esta es la misma pregunta real, con la única diferencia de ser el tercer argumento en el copyDatabasemétodo *, que es innecesario y, por lo tanto, una solución peor de la que el OP ya estaba al tanto. * cc @GurbakhshishSingh
Trindaz
164

Solución alternativa: puede volcar su base de datos y restaurarla en un nombre diferente. Como he experimentado, es mucho más rápido que db.copyDatabase().

$ mongodump -d old_db_name -o mongodump/
$ mongorestore -d new_db_name mongodump/old_db_name

http://docs.mongodb.org/manual/tutorial/backup-with-mongodump/

tomako
fuente
66
Esto es más rápido y, como "efecto secundario", su base de datos también está compactada.
Comtaler 01 de
¡Esto es genial! Ya tuve un mongodumpcreado. No sabía que puede restaurarlo con un nombre diferente. ¡Gracias!
Dushyant Bangal
55
NOTA: Esto no funciona si usa --gzipy crea un archivo
Dushyant Bangal
99
Esta es la forma recomendada ahora, ya db.copyDatabase()que ahora está en desuso
osolmaz
Al señalar que no, el argumento --db( -d) también está en desuso. Parece que ha habido una fiesta de desaprobación, dado copyDatabaseque también se ha ido. He tocado SERVER-701 con mis notas .
amcgregor
28

NOTA: Esperemos que esto haya cambiado en la última versión.

No puede copiar datos entre una instancia mongod de MongoDB 4.0 (independientemente del valor de FCV) y una instancia mongod de MongoDB 3.4 y anterior. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERTA : Hola amigos, tengan cuidado al copiar la base de datos, si no quieren estropear las diferentes colecciones en una sola base de datos.

A continuación se muestra cómo cambiar el nombre.

> show dbs;
testing
games
movies

Para cambiar el nombre, use la siguiente sintaxis

db.copyDatabase("old db name","new db name")

Ejemplo:

db.copyDatabase('testing','newTesting')

Ahora puede eliminar de forma segura el viejo db de la siguiente manera

use testing;

db.dropDatabase(); //Here the db **testing** is deleted successfully

Ahora solo piense qué sucede si intenta cambiar el nombre del nuevo nombre de la base de datos con el nombre de la base de datos existente

Ejemplo:

db.copyDatabase('testing','movies'); 

Entonces, en este contexto, todas las colecciones (tablas) de pruebas se copiarán a la base de datos de películas .

Channaveer Hakari
fuente
@amcgregor gracias por notificarme. He agregado un comentario para el mismo. Espero que ayude a alguien.
Channaveer Hakari
8

Aunque Mongodb no proporciona el comando para cambiar el nombre de la base de datos, sí proporciona el comando de colección Colección , que no solo modifica el nombre de la colección, sino que también modifica el nombre de la base de datos.

db.adminCommand({renameCollection: "db1.test1", to: "db2.test2"})

Este comando solo modifica los metadatos, el costo es muy pequeño, solo necesitamos recorrer todas las colecciones bajo db1, renombradas db2para lograr renombrar el nombre de la base de datos.
puedes hacerlo en este script Js

var source = "source";
var dest = "dest";
var colls = db.getSiblingDB(source).getCollectionNames();
for (var i = 0; i < colls.length; i++) {
var from = source + "." + colls[i];
var to = dest + "." + colls[i];
db.adminCommand({renameCollection: from, to: to});
}
HbnKing
fuente
¿Qué pasa con los índices y otros metadatos que se mantienen o pierden?
Udit Bhardwaj
@UDB Muy probablemente conservado. "Cambiar el nombre de una colección" es una transformación de espacio de nombres , esencialmente su colección nombrada foodentro de la barbase de datos tiene un espacio de nombres de bar.foo. El índice en por lo _idtanto tiene el espacio de nombres bar.foo._id_. Cambiar el nombre de la colección (debe) realizar una búsqueda de prefijo y reemplazar en todos los espacios de nombres que es consciente de, similar a la --nsFromy --nsTo opciones amongorestore .
amcgregor
1
¡El costo puede ser ENORME! docs.mongodb.com/manual/reference/command/renameCollection/… Si la base de datos de destino es la misma que la base de datos de origen, renameCollection simplemente cambia el espacio de nombres. Esta es una operación rápida. Si la base de datos de destino difiere de la base de datos de origen, renameCollection copia todos los documentos de la colección de origen a la colección de destino. Dependiendo del tamaño de la colección, esto puede tardar más en completarse.
Nagylzs
Por favor cambia tu respuesta. Su respuesta es útil, porque es posible mover una colección a otra base de datos con este comando. Pero es incorrecto y puede confundir a otros.
Nagylzs
6

El proceso anterior es lento, puede usar el siguiente método pero necesita mover colección por colección a otra base de datos.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})
madan ram
fuente
Excelente sugerencia en mi humilde opinión. Sin embargo, vale la pena señalar que esto no liberará el espacio del DB original, pero el cambio de nombre debería ser mucho más rápido que copiar los datos.
sirfz
1
Rasca eso, de todas formas hace una copia (ya que no elimina el espacio, no es realmente un simple cambio de nombre), por lo que este método no tiene una ventaja real sobre copiar y soltar.
sirfz
5

No existe un mecanismo para cambiar el nombre de las bases de datos. La respuesta actualmente aceptada al momento de escribir es objetivamente correcta y ofrece algunos detalles de fondo interesantes sobre la excusa aguas arriba, pero no ofrece sugerencias para replicar el comportamiento. Otras respuestas apuntan a copyDatabase, que ya no es una opción ya que la funcionalidad se ha eliminado en 4.0 . He actualizado SERVER-701 con mis notas e incredulidad. 🙃

El comportamiento equivalente implica mongodumpy mongorestoreen un poco de baile:

  1. Exporte sus datos, tomando nota de los "espacios de nombres" en uso. Por ejemplo, en uno de mis conjuntos de datos, tengo una colección con el espacio de nombres byzmcbehoomrfjcs9vlj.Analytics; ese prefijo (en realidad el nombre de la base de datos ) será necesario en el siguiente paso.

  2. Importa tus datos, suministros --nsFromy --nsToargumentos. ( Documentación. ) Continuando con mi ejemplo hipotético (y extremadamente ilegible) anterior, para restaurar a un nombre más sensible, invoco:

mongorestore --archive=backup.agz --gzip --drop \
    --nsFrom 'byzmcbehoomrfjcs9vlj.*' --nsTo 'rita.*'

Algunos también pueden señalar el --dbargumento de mongorestore, sin embargo, esto también está en desuso y desencadena una advertencia contra el uso en copias de seguridad de carpetas que no son BSON con una sugerencia completamente errónea de " use --nsInclude instead". La traducción del espacio de nombres anterior es equivalente al uso de la --dbopción, y es la configuración correcta para la manipulación del espacio de nombres, ya que no estamos intentando filtrar lo que se está restaurando.

amcgregor
fuente
1
--nsFromy --nsTotrabajó para mi ¡Gracias!
Bhargav Shah
mongodump con nsFrom / To son la respuesta oficial a partir de 2020
PaoloC
4

Traté de hacer.

db.copyDatabase('DB_toBeRenamed','Db_newName','host') 

y llegué a saber que la comunidad de mongo lo ha desaprobado aunque creó la copia de seguridad o cambió el nombre de DB.

WARNING: db.copyDatabase is deprecated. See http://dochub.mongodb.org/core/copydb-clone-deprecation
{
        "note" : "Support for the copydb command has been deprecated. See 
        http://dochub.mongodb.org/core/copydb-clone-deprecation",
        "ok" : 1
}

Entonces, no estoy convencido con el enfoque anterior, tuve que tomar Dump of local usando el siguiente comando

mongodump --host --db DB_TobeRenamed --out E://FileName/

conectado a Db.

use DB_TobeRenamed

entonces

db.dropDatabase()

luego restauró la base de datos con el comando.

mongorestore -host hostName -d Db_NewName E://FileName/
Abhishek kumar
fuente
2

En el caso de que coloque todos sus datos en la base de datos de administración (no debería hacerlo), notará db.copyDatabase()que no funcionará porque su usuario requiere muchos privilegios que probablemente no quiera otorgarle. Aquí hay un script para copiar la base de datos manualmente:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
François Guthmann
fuente