Propiedades calculadas en Azure Cosmos DB para NoSQL
SE APLICA A: NoSQL
Las propiedades calculadas de Azure Cosmos DB tienen valores derivados de las propiedades de elemento existentes, pero las propiedades no se conservan en los propios elementos. Las propiedades calculadas se limitan a un solo elemento y se les puede hacer referencia en consultas como si fueran propiedades persistentes. Las propiedades calculadas facilitan la escritura de lógica de consulta compleja una vez y hacerle referencia muchas veces. Puede agregar un único índice en estas propiedades, o bien usarlas como parte de un índice compuesto para aumentar el rendimiento.
Nota:
¿Tiene comentarios sobre las propiedades calculadas? Queremos conocerlos. No dude en compartir sus comentarios directamente con el equipo de ingeniería de Azure Cosmos DB: cosmoscomputedprops@microsoft.com.
¿Qué es una propiedad calculada?
Las propiedades calculadas deben estar en el nivel superior del elemento y no pueden tener una ruta de acceso anidada. Cada definición de propiedad calculada tiene dos componentes: un nombre y una consulta. El nombre es el nombre de la propiedad calculada y la consulta define la lógica para calcular el valor de propiedad de cada elemento. Las propiedades calculadas tienen como ámbito un elemento individual y, por tanto, no pueden usar valores de varios elementos ni depender de otras propiedades calculadas. Cada contenedor puede tener un máximo de 20 propiedades calculadas.
Ejemplo de definición de propiedad calculada:
{
"computedProperties": [
{
"name": "cp_lowerName",
"query": "SELECT VALUE LOWER(c.name) FROM c"
}
]
}
Restricciones de nombre
Recomendamos que asigne un nombre a las propiedades calculadas de forma que no se produzca una colisión con el nombre de una propiedad persistente. Para evitar la superposición de nombres de propiedad, puede agregar un prefijo o sufijo a todos los nombres de propiedad calculada. En este artículo se usa el prefijo cp_
en todas las definiciones de nombre.
Importante
La definición de una propiedad calculada utilizando el mismo nombre que una propiedad persistente no produce ningún error, pero puede provocar un comportamiento inesperado. Independientemente de si la propiedad calculada está indexada, los valores de las propiedades persistentes que comparten un nombre con una propiedad calculada no se incluirán en el índice. Las consultas siempre usarán la propiedad calculada en lugar de la persistente, con la excepción de que la propiedad persistente se devuelve en lugar de la calculada si hay una proyección con caracteres comodín en la cláusula SELECT. La proyección de caracteres comodín no incluye automáticamente las propiedades calculadas.
Las restricciones en los nombres de propiedades calculadas son las siguientes:
- Todas las propiedades calculadas deben tener nombres únicos.
- El valor de la propiedad
name
representa el nombre de propiedad de nivel superior que se puede usar para hacer referencia a la propiedad calculada. - Los nombres de propiedad del sistema reservados, como
id
,_rid
y_ts
no se pueden usar como nombres de propiedad calculada. - Un nombre de propiedad calculada no puede coincidir con una ruta de acceso de propiedad que ya está indexada. Esta restricción se aplica a todas las rutas de acceso de indexación especificadas, entre las que se incluyen:
- Rutas de acceso incluidas
- Rutas de acceso excluidas
- Índices espaciales
- Índices compuestos
Restricciones de consulta
Las consultas de la definición de propiedad calculada deben ser válidas sintáctica y semánticamente; de lo contrario, se produce un error en la operación de creación o actualización. Las consultas se deben evaluar como un valor determinista para todos los elementos de un contenedor. Las consultas pueden evaluarse como undefined o NULL para algunos elementos y las propiedades calculadas con valores undefined o NULL se comportan igual que las propiedades persistentes con valores undefined o NULL cuando se usan en consultas.
Las limitaciones en las definiciones de consultas de propiedad calculadas son las siguientes:
- Las consultas deben especificar una cláusula FROM que represente la referencia del elemento raíz. Algunos ejemplos de cláusulas FROM admitidas son
FROM c
,FROM root c
yFROM MyContainer c
. - Las consultas deben usar una cláusula VALUE en la proyección.
- Las consultas no pueden incluir una cláusula JOIN.
- Las consultas no pueden usar expresiones escalares no deterministas. Algunos ejemplos de expresiones escalares no deterministas son: GetCurrentDateTime, GetCurrentTimeStamp, GetCurrentTicks y RAND.
- Las consultas no pueden usar ninguna de las siguientes cláusulas: WHERE, GROUP BY, ORDER BY, TOP, DISTINCT, OFFSET LIMIT, EXISTS, ALL, LAST, FIRST y NONE.
- Las consultas no pueden incluir una subconsulta escalar.
- No se admiten funciones de agregado, espaciales, no deterministas ni definidas por el usuario (UDF).
Crear propiedades calculadas
Una vez creadas las propiedades calculadas, puede ejecutar consultas que hagan referencia a las propiedades mediante cualquier método, incluidos todos los kits de desarrollo de software (SDK) y Azure Data Explorer en Azure Portal.
Versión admitida | Notas | |
---|---|---|
.NET SDK v3 | >= 3.34.0-preview | Actualmente, las propiedades calculadas solo están disponibles en las versiones preliminares del paquete. |
SDK de Java v4 | >= 4.46.0 | Las propiedades calculadas están actualmente en versión preliminar. |
SDK de Python | >= v4.5.2b5 | Las propiedades calculadas están actualmente en versión preliminar. |
Creación de propiedades calculadas mediante el SDK
Puede crear un nuevo contenedor que tenga propiedades calculadas definidas o puede añadir propiedades calculadas a un contenedor existente.
Este es un ejemplo de cómo crear propiedades calculadas en un nuevo contenedor:
ContainerProperties containerProperties = new ContainerProperties("myContainer", "/pk")
{
ComputedProperties = new Collection<ComputedProperty>
{
new ComputedProperty
{
Name = "cp_lowerName",
Query = "SELECT VALUE LOWER(c.name) FROM c"
}
}
};
Container container = await client.GetDatabase("myDatabase").CreateContainerAsync(containerProperties);
Este es un ejemplo de cómo actualizar propiedades calculadas en un contenedor existente:
var container = client.GetDatabase("myDatabase").GetContainer("myContainer");
// Read the current container properties
var containerProperties = await container.ReadContainerAsync();
// Make the necessary updates to the container properties
containerProperties.Resource.ComputedProperties = new Collection<ComputedProperty>
{
new ComputedProperty
{
Name = "cp_lowerName",
Query = "SELECT VALUE LOWER(c.name) FROM c"
},
new ComputedProperty
{
Name = "cp_upperName",
Query = "SELECT VALUE UPPER(c.name) FROM c"
}
};
// Update the container with changes
await container.ReplaceContainerAsync(containerProperties);
Sugerencia
Cada vez que actualice las propiedades del contenedor, se sobrescriben los valores antiguos. Si tiene propiedades calculadas existentes y desea agregar otras nuevas, asegúrese de agregar propiedades calculadas nuevas y existentes a la colección.
Creación de propiedades calculadas mediante el Explorador de datos
Puede usar el Explorador de datos para crear una propiedad calculada para un contenedor.
Abra el contenedor existente en el Explorador de datos.
Vaya a la sección Configuración del contenedor. A continuación, vaya a la subsección *Propiedades calculadas .
Edite el JSON de definición de propiedades calculadas para el contenedor. En este ejemplo, este JSON se usa para definir una propiedad calculada para dividir la
SKU
cadena de un producto minorista mediante el-
delimitador.[ { "name": "cp_splitSku", "query": "SELECT VALUE StringSplit(p.sku, \"-\") FROM products p" } ]
Guarde la propiedad calculada.
Uso de propiedades calculadas en consultas
Se puede hacer referencia a las propiedades calculadas en las consultas de la misma manera que las propiedades persistentes. Los valores de las propiedades calculadas que no se indexan se evalúan durante el tiempo de ejecución mediante la definición de propiedad calculada. Si se indexa una propiedad calculada, el índice se usa de la misma manera que para las propiedades persistentes y la propiedad calculada se evalúa según sea necesario. Se recomienda agregar índices a las propiedades calculadas para obtener el mejor coste y rendimiento.
En los ejemplos siguientes se usa el conjunto de datos de productos de inicio rápido que está disponible en Data Explorer en Azure Portal. Para empezar, seleccione Iniciar el inicio rápido y cargue el conjunto de datos en un nuevo contenedor.
A continuación se muestra un ejemplo de elemento:
{
"id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"categoryId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
"categoryName": "Bikes, Touring Bikes",
"sku": "BK-T79U-50",
"name": "Touring-1000 Blue, 50",
"description": "The product called \"Touring-1000 Blue, 50\"",
"price": 2384.07,
"tags": [
{
"id": "cccccccc-2222-3333-4444-dddddddddddd",
"name": "Tag-61"
}
],
"_rid": "n7AmAPTJ480GAAAAAAAAAA==",
"_self": "dbs/n7AmAA==/colls/n7AmAPTJ480=/docs/n7AmAPTJ480GAAAAAAAAAA==/",
"_etag": "\"01002683-0000-0800-0000-6451fb4b0000\"",
"_attachments": "attachments/",
"_ts": 1683094347
}
Proyección
Si es necesario proyectar las propiedades calculadas, se les debe hacer referencia de forma explícita. Las proyecciones con caracteres comodín como SELECT *
devuelven todas las propiedades persistentes, pero no incluyen propiedades calculadas.
Este es un ejemplo de definición de propiedad calculada para convertir la propiedad name
a minúsculas:
{
"name": "cp_lowerName",
"query": "SELECT VALUE LOWER(c.name) FROM c"
}
Esta propiedad se podría proyectar en una consulta:
SELECT
c.cp_lowerName
FROM
c
WHERE, cláusula
Se puede hacer referencia a las propiedades calculadas en predicados de filtro como cualquier propiedad persistente. Se recomienda agregar los índices individuales o compuestos pertinentes al usar propiedades calculadas en filtros.
Este es un ejemplo de definición de propiedad calculada para calcular un descuento de precio del 20 %:
{
"name": "cp_20PercentDiscount",
"query": "SELECT VALUE (c.price * 0.2) FROM c"
}
Esta propiedad se podría filtrar para asegurarse de que solo se devuelvan los productos en los que el descuento sea inferior a 50 USD:
SELECT
c.price - c.cp_20PercentDiscount as discountedPrice,
c.name
FROM
c
WHERE
c.cp_20PercentDiscount < 50.00
Cláusula GROUP BY
Al igual que con las propiedades persistentes, se puede hacer referencia a las propiedades calculadas en la cláusula GROUP BY y usar el índice siempre que sea posible. Para obtener el mejor rendimiento, agregue los índices únicos o compuestos pertinentes.
Este es un ejemplo de definición de propiedad calculada que busca la categoría principal para cada elemento de la propiedad categoryName
:
{
"name": "cp_primaryCategory",
"query": "SELECT VALUE SUBSTRING(c.categoryName, 0, INDEX_OF(c.categoryName, ',')) FROM c"
}
Después, puede agrupar por cp_primaryCategory
para obtener el recuento de elementos de cada categoría principal:
SELECT
COUNT(1),
c.cp_primaryCategory
FROM
c
GROUP BY
c.cp_primaryCategory
Sugerencia
Aunque también puede conseguir esta consulta sin utilizar propiedades calculadas, su uso simplifica considerablemente la escritura de la consulta y permite un mayor rendimiento porque cp_primaryCategory
se puede indexar. Tanto SUBSTRING() como INDEX_OF() necesitan un examen completo de todos los elementos del contenedor, pero si indexa la propiedad calculada, en su lugar se puede atender toda la consulta desde el índice. La capacidad de atender la consulta desde el índice en lugar de depender de un examen completo aumenta el rendimiento y reduce los costos de unidad de solicitud (RU) de consulta.
Cláusula ORDER BY
Como sucede con las propiedades persistentes, se puede hacer referencia a las propiedades calculadas en la cláusula ORDER BY y deben estar indexadas para que la consulta se realice correctamente. Mediante el uso de propiedades calculadas, puede aplicar ORDER BY al resultado de funciones complejas lógicas o del sistema, lo que abre muchos nuevos escenarios de consulta cuando se usa Azure Cosmos DB.
Este es un ejemplo de definición de propiedad calculada que obtiene el mes del valor _ts
:
{
"name": "cp_monthUpdated",
"query": "SELECT VALUE DateTimePart('m', TimestampToDateTime(c._ts*1000)) FROM c"
}
Para poder usar ORDER BY en cp_monthUpdated
, debe agregarlo a la directiva de indexación. Una vez que actualice la directiva de indexación, puede ordenar por la propiedad calculada.
SELECT
*
FROM
c
ORDER BY
c.cp_monthUpdated
Propiedades calculadas de índice
Las propiedades calculadas no se indexan de forma predeterminada y no están cubiertas por rutas de acceso de comodín en la directiva de indexación. Puede agregar índices únicos o compuestos en las propiedades calculadas de la directiva de indexación de la misma manera que agregaría índices en las propiedades persistentes. Se recomienda agregar índices relevantes a todas las propiedades calculadas. Se recomiendan estos índices porque son beneficiosos para aumentar el rendimiento y reducir las unidades de solicitud (RU). Cuando se indexan las propiedades calculadas, los valores reales se evalúan durante las operaciones de escritura de elementos para generar y conservar los términos del índice.
Hay algunas consideraciones para indexar las propiedades calculadas, entre las que se incluyen las siguientes:
- Las propiedades calculadas se pueden especificar en rutas de acceso incluidas, rutas excluidas y rutas de acceso de índice compuestas
- Las propiedades calculadas no pueden tener definido un índice espacial en ellas
- Las rutas de acceso con caracteres comodín en la ruta de acceso de propiedad calculada funcionan como si fueran propiedades normales.
- También se deben quitar índices relacionados en una propiedad quitada e indizada.
Nota:
Todas las propiedades calculadas se definen en el nivel superior del elemento. La ruta de acceso siempre es /<computed property name>
.
Sugerencia
Cada vez que actualice las propiedades del contenedor, se sobrescriben los valores antiguos. Si tiene propiedades calculadas existentes y desea agregar otras nuevas, asegúrese de agregar propiedades calculadas nuevas y existentes a la colección.
Nota:
Cuando se modifica la definición de una propiedad calculada indizada, no se vuelve a indexar automáticamente. Para indexar la propiedad calculada modificada, primero deberá quitar la propiedad calculada del índice. Después de completar la reindexación, vuelva a agregar la propiedad calculada a la directiva de índice.
Si quiere eliminar una propiedad calculada, primero deberá quitarla de la directiva de índice.
Adición de un único índice para las propiedades calculadas
Para agregar un único índice para una propiedad calculada denominada cp_myComputedProperty
:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
},
{
"path": "/cp_myComputedProperty/?"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
]
}
Adición de un índice compuesto para las propiedades calculadas
Para agregar un índice compuesto en dos propiedades en las que una se calcula como cp_myComputedProperty
y la otra se persiste como myPersistedProperty
:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/\"_etag\"/?"
}
],
"compositeIndexes": [
[
{
"path": "/cp_myComputedProperty"
},
{
"path": "/path/to/myPersistedProperty"
}
]
]
}
Descripción del consumo de unidad de solicitud
La adición de propiedades calculadas a un contenedor no consume RU. Las operaciones de escritura en contenedores que tienen propiedades calculadas definidas pueden ver un ligero aumento de RU. Si se indexa una propiedad calculada, las RU en las operaciones de escritura aumentan para reflejar los costos de indexación y evaluación de la propiedad calculada.