Indexación en Azure Cosmos DB: introducciónIndexing in Azure Cosmos DB - Overview

SE APLICA A: SQL API

Azure Cosmos DB es una base de datos independiente del esquema que le permite iterar en la aplicación sin tener que tratar con la administración de esquemas o índices.Azure Cosmos DB is a schema-agnostic database that allows you to iterate on your application without having to deal with schema or index management. De forma predeterminada, Azure Cosmos DB indexa automáticamente todas las propiedades de todos los elementos de su contenedor sin tener que definir ningún esquema ni configurar índices secundarios.By default, Azure Cosmos DB automatically indexes every property for all items in your container without having to define any schema or configure secondary indexes.

El objetivo de este artículo es explicar cómo Azure Cosmos DB indexa datos y cómo usa índices para mejorar el rendimiento de las consultas.The goal of this article is to explain how Azure Cosmos DB indexes data and how it uses indexes to improve query performance. Se recomienda revisar esta sección antes de explorar cómo personalizar las directivas de indexación.It is recommended to go through this section before exploring how to customize indexing policies.

De elementos a árbolesFrom items to trees

Cada vez que un elemento se almacena en un contenedor, su contenido se proyecta como un documento JSON y luego se convierte en una representación de árbol.Every time an item is stored in a container, its content is projected as a JSON document, then converted into a tree representation. Eso significa que todas las propiedades de ese elemento se representan como nodos de un árbol.What that means is that every property of that item gets represented as a node in a tree. Para todas las propiedades de primer nivel del elemento, se crea un pseudonodo raíz como elemento primario.A pseudo root node is created as a parent to all the first-level properties of the item. Los nodos hoja contienen los valores escalares reales pertenecientes a un elemento.The leaf nodes contain the actual scalar values carried by an item.

Por ejemplo, considere este elemento:As an example, consider this item:

    {
        "locations": [
            { "country": "Germany", "city": "Berlin" },
            { "country": "France", "city": "Paris" }
        ],
        "headquarters": { "country": "Belgium", "employees": 250 },
        "exports": [
            { "city": "Moscow" },
            { "city": "Athens" }
        ]
    }

Se podría representar mediante el árbol siguiente:It would be represented by the following tree:

El elemento anterior representado como árbol

Observe cómo se codifican las matrices en el árbol: cada entrada de una matriz obtiene un nodo intermedio etiquetado con el índice de esa entrada dentro de la matriz (0, 1, etc.).Note how arrays are encoded in the tree: every entry in an array gets an intermediate node labeled with the index of that entry within the array (0, 1 etc.).

De árboles a rutas de acceso de propiedadesFrom trees to property paths

El motivo por el que Azure Cosmos DB transforma los elementos en árboles es porque permite hacer referencia a las propiedades mediante sus rutas de acceso dentro de esos árboles.The reason why Azure Cosmos DB transforms items into trees is because it allows properties to be referenced by their paths within those trees. Para obtener la ruta de acceso de una propiedad, podemos recorrer el árbol desde el nodo raíz hasta esa propiedad y concatenar las etiquetas de cada nodo recorrido.To get the path for a property, we can traverse the tree from the root node to that property, and concatenate the labels of each traversed node.

Estas son las rutas de acceso de cada propiedad del elemento de ejemplo descrito anteriormente:Here are the paths for each property from the example item described above:

  • /locations/0/country: "Germany"/locations/0/country: "Germany"
  • /locations/0/city: "Berlin"/locations/0/city: "Berlin"
  • /locations/1/country: "France"/locations/1/country: "France"
  • /locations/1/city: "Paris"/locations/1/city: "Paris"
  • /headquarters/country: "Belgium"/headquarters/country: "Belgium"
  • /headquarters/employees: 250/headquarters/employees: 250
  • /exports/0/city: "Moscow"/exports/0/city: "Moscow"
  • /exports/1/city: "Athens"/exports/1/city: "Athens"

Cuando se escribe un elemento, Azure Cosmos DB indexa eficazmente la ruta de acceso de cada propiedad y su valor correspondiente.When an item is written, Azure Cosmos DB effectively indexes each property's path and its corresponding value.

Tipos de índiceTypes of indexes

Actualmente, Azure Cosmos DB admite tres tipos de índices.Azure Cosmos DB currently supports three types of indexes. Puede configurar estos tipos de índice al definir la directiva de indexación.You can configure these index types when defining the indexing policy.

Índice de rangosRange Index

El índice de rangos se basa en una estructura de árbol ordenada.Range index is based on an ordered tree-like structure. El tipo de índice de rango se usa para:The range index type is used for:

  • Consultas de igualdad:Equality queries:

    SELECT * FROM container c WHERE c.property = 'value'
    
    SELECT * FROM c WHERE c.property IN ("value1", "value2", "value3")
    

    Coincidencia de igualdad numérica en un elemento de matrizEquality match on an array element

      SELECT * FROM c WHERE ARRAY_CONTAINS(c.tags, "tag1")
    
  • Consultas por rango:Range queries:

    SELECT * FROM container c WHERE c.property > 'value'
    

    (funciona para >, <, >=, <=, !=).(works for >, <, >=, <=, !=)

  • Comprobación de la presencia de una propiedad:Checking for the presence of a property:

    SELECT * FROM c WHERE IS_DEFINED(c.property)
    
  • Funciones del sistema de cadena:String system functions:

    SELECT * FROM c WHERE CONTAINS(c.property, "value")
    
    SELECT * FROM c WHERE STRINGEQUALS(c.property, "value")
    
  • Consultas ORDER BY:ORDER BY queries:

    SELECT * FROM container c ORDER BY c.property
    
  • Consultas JOIN:JOIN queries:

    SELECT child FROM container c JOIN child IN c.properties WHERE child = 'value'
    

Los índices de rango se pueden usar en valores escalares (cadena o número).Range indexes can be used on scalar values (string or number). La directiva de indexación predeterminada para los contenedores recién creados exige que se usen índices de intervalo para todas las cadenas o números.The default indexing policy for newly created containers enforces range indexes for any string or number. Para obtener información sobre cómo configurar los índices de rango, consulte los ejemplos de la directiva de indexación de rangos.To learn how to configure range indexes, see Range indexing policy examples

Índice espacialSpatial index

Los índices espaciales permiten realizar consultas eficaces en objetos geoespaciales como puntos, líneas, polígonos y multipolígonos.Spatial indices enable efficient queries on geospatial objects such as - points, lines, polygons, and multipolygon. Estas consultas usan las palabras clave ST_DISTANCE, ST_WITHIN, ST_INTERSECTS.These queries use ST_DISTANCE, ST_WITHIN, ST_INTERSECTS keywords. A continuación se muestran algunos ejemplos que usan el tipo de índice espacial:The following are some examples that use spatial index type:

  • Consultas de distancia geoespaciales:Geospatial distance queries:

    SELECT * FROM container c WHERE ST_DISTANCE(c.property, { "type": "Point", "coordinates": [0.0, 10.0] }) < 40
    
  • Información geoespacial dentro de consultas:Geospatial within queries:

    SELECT * FROM container c WHERE ST_WITHIN(c.property, {"type": "Point", "coordinates": [0.0, 10.0] })
    
  • Consultas de intersecciones geoespaciales:Geospatial intersect queries:

    SELECT * FROM c WHERE ST_INTERSECTS(c.property, { 'type':'Polygon', 'coordinates': [[ [31.8, -5], [32, -5], [31.8, -5] ]]  })  
    

Los índices espaciales pueden usarse en objetos GeoJSON con un formato correcto.Spatial indexes can be used on correctly formatted GeoJSON objects. Actualmente, se admiten Points, LineStrings, Polygons y MultiPolygons.Points, LineStrings, Polygons, and MultiPolygons are currently supported. Para usar este tipo de índice, establézcalo mediante la propiedad "kind": "Range" al configurar la directiva de indexación.To use this index type, set by using the "kind": "Range" property when configuring the indexing policy. Para obtener información sobre cómo configurar los índices espaciales, vea ejemplos de la directiva de indexación espacial.To learn how to configure spatial indexes, see Spatial indexing policy examples

Índices compuestosComposite indexes

Los índices compuestos aumentan la eficacia al realizar operaciones en varios campos.Composite indices increase the efficiency when you are performing operations on multiple fields. El tipo de índice compuesto se usa con:The composite index type is used for:

  • Consultas ORDER BY en varias propiedades:ORDER BY queries on multiple properties:
 SELECT * FROM container c ORDER BY c.property1, c.property2
  • Consultas con un filtro y ORDER BY.Queries with a filter and ORDER BY. Estas consultas pueden emplear un índice compuesto si la propiedad de filtro se agrega a la cláusula ORDER BY.These queries can utilize a composite index if the filter property is added to the ORDER BY clause.
 SELECT * FROM container c WHERE c.property1 = 'value' ORDER BY c.property1, c.property2
  • Consultas con un filtro en dos o más propiedades en las que al menos una propiedad es un filtro de igualdadQueries with a filter on two or more properties where at least one property is an equality filter
 SELECT * FROM container c WHERE c.property1 = 'value' AND c.property2 > 'value'

Siempre y cuando un predicado de filtro use un tipo de índice, el motor de consultas evaluará ese primero antes de examinar el resto.As long as one filter predicate uses one of the index type, the query engine will evaluate that first before scanning the rest. Por ejemplo, si tiene una consulta SQL como SELECT * FROM c WHERE c.firstName = "Andrew" and CONTAINS(c.lastName, "Liu")For example, if you have a SQL query such as SELECT * FROM c WHERE c.firstName = "Andrew" and CONTAINS(c.lastName, "Liu")

  • La consulta anterior primero filtrará las entradas en las que firstName = "Andrew" mediante el índice.The above query will first filter for entries where firstName = "Andrew" by using the index. Después, pasa todas las entradas firstName = "Andrew" a través de una canalización subsiguiente para evaluar el predicado de filtro CONTAINS.It then pass all of the firstName = "Andrew" entries through a subsequent pipeline to evaluate the CONTAINS filter predicate.

  • Puede acelerar las consultas y evitar exámenes de todo el contenedor cuando emplee funciones que no usen el índice (por ejemplo, CONTAINS) mediante la incorporación de predicados de filtro adicionales que utilicen el índice.You can speed up queries and avoid full container scans when using functions that don't use the index (e.g. CONTAINS) by adding additional filter predicates that do use the index. El orden de las cláusulas de filtro no es importante.The order of filter clauses isn't important. El motor de consultas determinará qué predicados son más selectivos y ejecutará la consulta en consecuencia.The query engine is will figure out which predicates are more selective and run the query accordingly.

Para obtener información sobre cómo configurar los índices compuestos, consulte los ejemplos de la directiva de indexación compuesta.To learn how to configure composite indexes, see Composite indexing policy examples

Consultas con índicesQuerying with indexes

Las rutas de acceso extraídas al indexar datos facilitan la tarea de buscar el índice al procesar una consulta.The paths extracted when indexing data make it easy to lookup the index when processing a query. Al comparar la cláusula WHERE de una consulta con la lista de rutas de acceso indexadas, es posible identificar rápidamente los elementos que coinciden con el predicado de consulta.By matching the WHERE clause of a query with the list of indexed paths, it is possible to identify the items that match the query predicate very quickly.

Por ejemplo, considere la consulta siguiente: SELECT location FROM location IN company.locations WHERE location.country = 'France'.For example, consider the following query: SELECT location FROM location IN company.locations WHERE location.country = 'France'. El predicado de consulta (filtrado por elementos, donde cualquier ubicación tiene "France" como su país) coincidiría con la ruta de acceso resaltada en rojo a continuación:The query predicate (filtering on items, where any location has "France" as its country/region) would match the path highlighted in red below:

Coincidencia con una ruta de acceso específica dentro de un árbol

Nota

Una cláusula ORDER BY que ordena por una sola propiedad siempre necesita un índice de rango y dará error si la ruta de acceso a la que hace referencia no tiene uno.An ORDER BY clause that orders by a single property always needs a range index and will fail if the path it references doesn't have one. Del mismo modo, una consulta ORDER BY que se ordena por varias propiedades siempre necesita un índice compuesto.Similarly, an ORDER BY query which orders by multiple properties always needs a composite index.

Pasos siguientesNext steps

Obtenga más información acerca de la indexación en los siguientes artículos:Read more about indexing in the following articles: