2010-11-23 31 views
13

He creado varios sitios basados ​​en Python que utilizan mongodb como base de datos y estoy muy contento con su sistema ObjectId; sin embargo, me encantaría poder codificar los identificadores de una manera más breve sin crear una colección de mapas o utilizando un servicio url-acortador.¿Cómo se pueden acortar los ID de mongo para un mejor uso en las URL?

Sugerencias? ¿Historias de éxito?

Respuesta

7

Heh, recientemente quería exactamente lo mismo.

Lo que terminé haciendo es dar a cada documento que necesita una "identificación pública" que es única (como el ObjectId), pero eso es solo un número de incremento automático (por lo que tomará un tiempo antes los números se hacen enormes, y aún más si están codificados en hexadecimal). De esta forma, puedo usar el ObjectId internamente (que sospecho que es más rápido) y buscar documentos referenciados externamente usando su identificación pública.

Tenga en cuenta que hay un pequeño impacto en el rendimiento al crear estos identificadores públicos, ya que cada uno requiere una actualización atómica de un documento (por lo que solo debe usarlos donde los necesite).

La clave para crear un número de incremento automático es findAndModify command de MongoDB para incrementar un valor y devolver el valor anterior en una sola operación atómica.

Dado que está utilizando Python, y yo también, aquí está el código que estoy utilizando actualmente (tenga en cuenta que no es en la producción aún):

from pymongo import Connection 
from pymongo.son import SON 

db = Connection().mydatabase 

PUBLIC_ID_COLLECTION = 'next_public_id' 
def next_public_id(): 
    result = db.command(SON({ 'findandmodify': PUBLIC_ID_COLLECTION }, 
     query = { '_id': 'manager' }, 
     update = { '$inc': { 'next_public_id': 1 } }, 
     upsert = True  # Insert if not already existing 
    )) 
    manager = result['value'] 
    return manager.get('next_public_id', 0) 
12

Usted puede comprimirlos como números Base62 . Esto no ahorra mucho espacio, pero le ahorra unos pocos bytes por ID. Mi ejemplo es Ruby, pero un uso similar en Python no sería difícil.

ree-1.8.7-2010.02 > User.first._id.to_s 
=> "4c76f3dd98db74697500003b" 

ree-1.8.7-2010.02 > User.first._id.to_s.to_i(16).base62_encode 
=> "uMarF7LmpY3bNOSn" 
+0

¿Cómo decodificar? Además, al buscar el recurso, ¿es más rápido decodificar y luego buscar por _id o simplemente agregar un índice al campo codificado de base62? – user1071182

+0

Estoy usando el paquete nodo base62 https://npmjs.org/package/base62 Observe que la decodificación no funciona correctamente> id '513fce0fcaa8ed9819000002' > enc = base62.encode (parseInt (id, 16)) ' wHzaphe07ek80CC8 ' > base62.decode (enc) .toString (16) ' 513fce0fcaa8ec0000000000 – user1071182

+0

Resulta que el número es demasiado grande para javascript. Terminé usando la codificación base58 y dividiendo el número a la mitad y funciona correctamente. > aenc = Base58.encode (parseInt (id.substring (0,12), 16)); 'GsEAfTs9' > benc = Base58.encode (parseInt (id.subcadena (12, 24), 16)); '33jgsdqRG' > Base58.decode (aenc) .toString (16) + Base58.decode (benc) .toString (16); '513fce0fcaa8ed9819000002' Todavía tengo curiosidad sobre el índice vs decodificación – user1071182

1

Si está tratando de conservar el valor original, entonces realmente no hay una buena manera. Podrías codificarlo, pero la probabilidad de que sea más pequeño es mínimo. Podría hash, pero luego no es reversible.

Si este es un REQUISITO, probablemente recomendaría crear una tabla o colección de búsqueda en la que un pequeño número incremental haga referencia a las entradas en una Colección Mongo.

1

Traje este tema hace un tiempo en la lista de correo de mongodb. Vea si puede ayudarlo.

Custom _id

0

Si usted puede generar números únicos de incremento automático, no hay absolutamente ninguna necesidad de utilizar OBJECTID para _id. Hacer esto en un entorno distribuido probablemente sea más costoso que usar ObjectId. Esa es tu compensación.

Cuestiones relacionadas