2012-06-18 58 views
7

Estoy usando java/morphia para tratar con mongodb. El ObjectId predeterminado no es muy conveniente para usar desde la capa de Java. Me gustaría hacerlo de tipo String mientras mantengo el proceso de generación de claves usando ObjectId, digamos _id = new ObjectId.toString().¿Puedo usar String como tipo de ID para el documento mongodb?

Quiero saber si hay algún efecto secundario al hacerlo de esta manera? Por ejemplo, ¿afectará el rendimiento de la base de datos o causará conflictos clave en cualquier medio? ¿Afectará el entorno de fragmentación ...

+0

¿Puede explicarme más acerca de por qué ObjectId es inconveniente? Puede recrear fácilmente uno de una cadena como 'id = new ObjectId (str)' –

+0

String es el tipo utilizado en cada programa Java, mientras que ObjectId no lo es. No quiero introducir un tipo nuevo a otros componentes que usan mi biblioteca. probablemente se necesite importar morphia, mongodb y bson library, aún es mejor si las personas que usan mi biblioteca son transparentes para mongodb, incluyendo ObjectId –

+0

Hmm ... pero si su biblioteca está almacenando datos en Mongo, ¿no será mongo.jar? ¿Necesito estar en el classpath de todos modos? Además, hay una sobrecarga de creación y recolección de basura de cadenas. –

Respuesta

18

Puede utilizar cualquier tipo de valor para un campo _id (excepto Matrices). Si eliges no usar ObjectId, deberás garantizar de algún modo la unicidad de los valores (la conversión de ObjectId a string lo hará). Si intentas insertar una clave duplicada, se producirá un error y tendrás que lidiar con ella.

No estoy seguro de qué efecto tendrá en el clúster fragmentado cuando intente insertar dos documentos con el mismo _id en fragmentos diferentes. Sospecho que te dejará insertar, pero esto te morderá más tarde. (Tendré que probar esto).

Dicho esto, no debería tener problemas con _id = (new ObjectId).toString().

+0

Eso está bien. ¡Gracias! –

+0

Tu segunda y tercera oración son una contra la otra. El tercero es correcto No sospeche en las respuestas. Además, '_id's puede contener el valor de tipo' array'. – Dyin

+0

¿Cómo se contradicen exactamente? –

4

De hecho, hice lo mismo porque estaba teniendo algún problema al convertir ObjectId a JSON.

luego hice algo así como

@Id 
private String id; 
public String getId() { 
    return id(); 
} 
public void setId(String id) { 
    this.id = id; 
} 

y todo funcionaba bien hasta que me decidí a actualizar un documento previamente insertado, cuando llegué el objeto por Id enviado a la página a través de JSON y recibir el mismo objeto actualizado también por publicación JSON y luego usó la función de guardar del Datastore, en lugar de actualizar los datos anteriores, insertó un nuevo documento en lugar de actualizar el que ya estaba.

Incluso peor, el nuevo documento tenía la misma ID que la anterior, algo que pensé que era imposible.

De todos modos, establecí el objeto privado como un ObjectID y simplemente dejé el conjunto get como una cadena y luego funcionó como se esperaba, no estoy seguro de que ayude en su caso pensado.

@Id 
private ObjectId id; 
public String getId() { 
    return id.toString(); 
} 
public void setId(String id) { 
    this.id = new ObjectId(id); 
} 
1

Sí, puede usar una cadena como su _id.

Lo recomendaría solo si tiene algún valor (en el documento) que, naturalmente, es una buena clave única. Usé este diseño en una colección donde había una etiqueta geográfica de cadena, de la forma "xxxxyyyy"; este campo único por documento iba a tener que estar en el documento y. Tenía que crear un índice en él ... ¿por qué no utilizarlo como clave? (Esto evitó un par clave-valor adicional, Y evitó un segundo índice en la colección, ya que MondoDB construye naturalmente un índice en "_id". Dado el tamaño de la colección, ambos agregaron algunos ahorros de espacio importantes.)

Sin embargo, por el tono de su pregunta ("ObjectIDs no son muy convenientes"), si la única razón por la que desea utilizar una cadena es que no desea preocuparse por averiguar cómo administrar ordenadamente ObjectID. Sugeriría que valga la pena su tiempo para entenderlos. Estoy seguro de que no son un problema ... una vez que hayas descubierto tu problema con ellos.

De lo contrario: ¿cuáles son sus opciones? ¿Confeccionará identificadores de cadena CADA VEZ que use un MongoDB en el futuro?

+1

Hola, gracias por volver a mi pregunta hecha hace casi cuatro años. Creo que tengo más comprensión sobre MongoDB desde entonces. Y ahora considero que almacenar ObjectId como una cadena realmente es una mala idea, porque ObjectId es literalmente tres enteros, mientras que la representación de Cadena de 24 caracteres, que no es eficiente en términos de espacio y tiempo. –

1

Me gustaría añadir que no siempre es una buena idea usar el ID de objeto BSON generado automáticamente como un identificador único, si se pasa a la aplicación: potencialmente puede ser manipulado por el usuario. Los ObjectID parecen generarse de forma secuencial, por lo que si no implementa los mecanismos de autorización necesarios, el usuario malintencionado simplemente podría incrementar el valor que tiene para acceder a recursos a los que no debería tener acceso.

Por lo tanto, el uso de identificadores de tipo UUID proporcionará una capa de seguridad a través de la oscuridad. Por supuesto, la Autorización (este usuario tiene permitido acceder al recurso solicitado) es una necesidad, pero debe tener en cuenta la característica ObjectID antes mencionada.

Para obtener lo mejor de ambos mundos, genere un UUID que coincida con la longitud de su ObjectID (12 o 24 caracteres) y úselo para crear su propio _id de tipo ObjectID.

+2

"si no implementa la autorización necesaria" está condenado de todos modos. La oscuridad no es seguridad. Solo te engaña a ti mismo "estamos a salvo". – Piohen

+0

@Piohen cómo la gente deja de leer el segundo párrafo me supera ... –

Cuestiones relacionadas