El patrón de atributos es un patrón de diseño de esquemas que ayuda a organizar documentos con muchos campos similares, especialmente cuando los campos comparten características comunes. Si necesitas ordenar o query en estos subconjuntos de campos similares, el patrón de atributo puede optimizar tu esquema. Permite una indexación más sencilla de documentos al consolidar varios campos similares por documento en un subdocumento de clave-valor. En lugar de crear múltiples índices en varios campos similares, el patrón de atributos permite crear menos índices, facilitando y agilizando la redacción de las queries.
Utilice el atributo patrón si alguna de las siguientes condiciones se aplica a su colección:
Tiene documentos grandes que contienen muchos campos similares con características compartidas que desea ordenar o consultar.
Un pequeño subconjunto de los documentos contiene los campos necesarios para la clasificación.
Acerca de esta tarea
Consideremos una colección de películas. Los documentos típicos de la colección podrían ser así:
db.movies.insertOne( { "_id": 1, "title": "Star Wars", "runtime": 121, "directors": ["George Lucas"], release_US: ISODate("1977-05-20T01:00:00+01:00"), release_France: ISODate("1977-10-19T01:00:00+01:00"), release_Italy: ISODate("1977-10-20T01:00:00+01:00"), release_UK: ISODate("1977-12-27T01:00:00+01:00") } )
Tenga en cuenta los múltiples campos de fecha de lanzamiento para diferentes países en el documento anterior. Si desea buscar una fecha de lanzamiento, debe consultar varios campos a la vez. Sin el patrón de atributos, necesitaría crear varios índices en el movies Colección para realizar búsquedas rápidas de fechas de lanzamiento:
db.movies.createIndex({ release_US: 1 }); db.movies.createIndex({ release_France: 1 }); db.movies.createIndex({ release_Italy: 1 }); db.movies.createIndex({ release_UK: 1 });
Sin embargo, los índices son costosos y pueden ralentizar el rendimiento, especialmente en las operaciones de escritura. El siguiente procedimiento demuestra cómo puedes aplicar el patrón de atributo en la colección movies, moviendo el subconjunto de información de diferentes fechas de publicación a un arreglo, reduciendo la necesidad de indexación.
Pasos
Agrupar subconjuntos de datos en una matriz.
Reorganice el esquema para convertir los distintos campos de fecha de lanzamiento en una matriz de pares clave-valor:
db.movies.insertOne( { "_id": 1, "title": "Star Wars", "runtime": 121, "directors": ["George Lucas"], releases: [ { location: "USA", date: ISODate("1977-05-20T01:00:00+01:00") }, { location: "France", date: ISODate("1977-10-19T01:00:00+01:00") }, { location: "Italy", date: ISODate("1977-10-20T01:00:00+01:00") }, { location: "UK", date: ISODate("1977-12-27T01:00:00+01:00") } ] } )
Resultados
Si un documento tiene varios campos que rastrean características iguales o similares, el patrón de atributos evita la necesidad de crear índices en cada campo similar. Al consolidar campos similares en una matriz y crear un índice en ella, se reduce el número total de índices necesarios y se mejora el rendimiento de las consultas.
Otros casos de uso
El patrón de atributos puede ser útil cuando el documento describe las características de los artículos. Algunos productos, como la ropa, pueden tener tallas pequeñas, medianas o grandes. Otros productos de la misma colección pueden expresarse en volumen, mientras que otros pueden expresarse en dimensiones físicas o peso.
Por ejemplo, considere una colección de botellas de agua. Un documento que no utiliza el patrón de atributo podría tener este aspecto:
db.bottles.insertOne([ { "_id": 1, "volume_ml": 500, "volume_ounces": 12 } ])
El siguiente código aplica el atributo patrón a la colección bottles:
db.bottles.insertOne([ { "_id": 1, specs: [ { k: "volume", v: "500", u: "ml" }, { k: "volume", v: "12", u: "ounces" }, ] } ])
Dado que los campos volume_ml y volume_ounces del primer documento contienen información similar, el esquema anterior los consolida en un solo campo, specs. El campo specs agrupa la información sobre las especificaciones de medida de una botella de agua determinada: el campo k especifica el valor medido, el v el valor y el u la unidad de medida.
El patrón de atributos también permite agrupar campos similares con nombres diferentes. Al especificar atributos mediante pares clave-valor, como el campo k, que especifica lo que se mide, se puede almacenar una mayor variedad de campos similares en una matriz, lo que minimiza la cantidad de índices necesarios para consultar los datos de forma eficiente.
Por ejemplo, considere este documento en la colección bottles que no utiliza el patrón de atributo. Este documento almacena especificaciones sobre el volumen y la altura de la botella de agua:
db.bottles.insertOne([ { "_id": 1, "volume_ml": 500, "volume_ounces": 12, "height_inches": 8 } ])
El siguiente código aplica el patrón de atributo al documento. Agrupa los campos volume_ml, volume_ounces y height_inches en la matriz specs:
db.bottles.insertOne([ { "_id": 1, specs: [ { k: "volume", v: "500", u: "ml" }, { k: "volume", v: "12", u: "ounces" }, { k: "height", v: "8", u: "inches" } ] } ])
El uso de pares clave-valor, como k, v y u, ofrece mayor flexibilidad en cuanto a los campos que se pueden agregar a la matriz. Cuantos más campos se puedan consolidar en la matriz, menos índices se necesitarán crear, lo que maximiza el rendimiento de las consultas.