Compartilhar via


Gerenciar a indexação no Azure DocumentDB

Índices são estruturas que melhoram a velocidade de recuperação de dados fornecendo acesso rápido a campos em uma coleção. Eles funcionam criando um conjunto ordenado de ponteiros para dados, geralmente com base em campos-chave. O Azure DocumentDB utiliza índices em vários contextos, incluindo otimização de consulta, restrições exclusivas e sharding.

Importante

O campo "_id" é o único campo indexado por padrão e o tamanho máximo do campo pode ser 2 KB. É recomendável adicionar índices adicionais com base em filtros de consulta e predicados para otimizar o desempenho.

Tipos de índice

Para simplificar, vamos considerar um exemplo de um aplicativo de blog com a seguinte configuração:

  • Nome do banco de dados: cosmicworks
  • Nome da coleção: products

Este aplicativo de exemplo armazena artigos como documentos com a estrutura a seguir. Todo o exemplo citado utiliza ainda mais a estrutura dessa coleção.

{
  "_id": ObjectId("617a34e7a867530bff1b2346"),
  "title": "Azure DocumentDB - A Game Changer",
  "content": "Azure DocumentDB is a globally distributed, multi-model database service.",
  "author": {lastName: "Doe", firstName: "John"},
  "category": "Technology",
  "launchDate": ISODate("2024-06-24T10:08:20.000Z"),
  "published": true
}

Índices de campo único

Índices de campo único armazenam informações de um único campo em uma coleção. A ordem de classificação do índice de campo único não importa. _id O campo permanece indexado por padrão.

O Azure DocumentDB dá suporte à criação de índice a seguir

  • Campos de documento de nível superior.
  • Documento inserido.
  • Campos no documento inserido.

O comando a seguir cria um único índice de campo no campo author e o comando a seguir o cria em um campo firstNameinserido.

use cosmicworks

db.products.createIndex({"author": 1})

// indexing embedded property
db.products.createIndex({"author.firstName": -1})

Uma consulta pode usar vários índices de campo único quando disponível.

Observação

O Azure DocumentDB permite a criação de no máximo 64 índices em uma coleção. Dependendo da camada, podemos planejar uma extensão de até 300 índices mediante solicitação.

Índices compostos

Os índices compostos melhoram o desempenho do banco de dados, permitindo consultas e classificações eficientes com base em vários campos dentro de documentos. Essa otimização reduz a necessidade de examinar coleções inteiras, acelerando a recuperação de dados e a organização.

O comando a seguir cria um índice composto nos campos author e launchDate em ordem de classificação oposta.

use cosmicworks

db.products.createIndex({"author":1, "launchDate":-1})

A Order de campos afeta a seletividade ou a utilização do índice. A find consulta não utilizaria o índice criado.

use cosmicworks

db.products.find({"launchDate": {$gt: ISODate("2024-06-01T00:00:00.000Z")}})

Limitações

  • Máximo de 32 campos\caminhos em um índice composto.

Índices parciais

Índices que têm um filtro de consulta associado que descreve quando gerar um termo no índice.

use cosmicworks

db.products.createIndex (
   { "author": 1, "launchDate": 1 },
   { partialFilterExpression: { "launchDate": { $gt: ISODate("2024-06-24T10:08:20.000Z") } } }
)

Limitações

  • Índices parciais não dão suporte a ORDER BY ou UNIQUE, a menos que o filtro os qualifique.

Índices de texto

Índices de texto são estruturas de dados especiais que otimizam consultas baseadas em texto, tornando-as mais rápidas e eficientes.

Use o createIndex método com a opção text para criar um índice de texto no title campo.

use cosmicworks;

db.products.createIndex({ title: "text" })

Observação

Embora você possa definir apenas um índice de texto por coleção, o Azure DocumentDB permite criar índices de texto em combinação de vários campos para permitir que você execute pesquisas de texto em diferentes campos em seus documentos.

Configurar opções de índice de texto

Os índices de texto no Azure DocumentDB vêm com várias opções para personalizar seu comportamento. Por exemplo, você pode especificar o idioma para análise de texto, definir pesos para priorizar determinados campos e configurar pesquisas que não diferenciam maiúsculas de minúsculas. Aqui está um exemplo de criação de um índice de texto com opções:

  • Crie um índice para dar suporte à pesquisa nos campos title e content com suporte ao idioma inglês. Além disso, atribua pesos mais altos ao title campo para priorizá-lo nos resultados da pesquisa.

    use cosmicworks
    
    db.products.createIndex(
        { title: "text", content: "text" },
        { default_language: "english", weights: { title: 10, content: 5 }, caseSensitive: false }
    )
    

Observação

Quando um cliente executa uma consulta de pesquisa de texto com o termo "DocumentDB", a pontuação de cada documento na coleção será calculada com base na presença e frequência do termo nos campos "título" e "conteúdo", com maior importância dada ao campo "título" devido ao seu peso mais alto.

Executar uma pesquisa de texto usando um índice de texto

Depois que o índice de texto for criado, você poderá executar pesquisas de texto usando o operador "text" em suas consultas. O operador de texto utiliza uma cadeia de caracteres de pesquisa e a compara com o índice de texto para encontrar documentos relevantes.

  • Execute uma pesquisa de texto para a frase DocumentDB.

    use cosmicworks
    
    db.products.find(
      { $text: { $search: "DocumentDB" } }
    )
    
  • Opcionalmente, use o operador de projeção $meta junto com o campo textScore em uma consulta para ver o peso.

    use cosmicworks
    
    db.products.find(
    { $text: { $search: "DocumentDB" } },
    { score: { $meta: "textScore" } }
    )
    

Limitações

  • Somente um índice de texto pode ser configurado em uma coleção.
  • As operações de classificação não podem usar a ordenação do índice de texto no MongoDB.
  • Não há suporte para hint() em combinação com uma consulta usando $text expressão.
  • Índices de texto podem ser relativamente grandes, consumindo espaço de armazenamento significativo em comparação com outros tipos de índice.

Índices curinga

Índice em um único campo, indexa todos os caminhos abaixo do field , excluindo outros campos que estão no mesmo nível. Por exemplo, para o documento de exemplo a seguir

{
 "children":
    {
     "familyName": "Merriam",
     "pets": { "details": {“name”: "Goofy", ”age”: 3} }
   } 
}

Criando um índice em { "pets.$**": 1 }, cria índice sobre detalhes e propriedades de subdocumento, mas não cria um índice em "familyName".

Limitações

  • Índices curinga não dão suporte a índices exclusivos.
  • Índices curinga não dão suporte a pushdowns de ORDER BY, a menos que o filtro inclua apenas caminhos presentes no curinga (já que eles não indexam elementos indefinidos)
  • Um índice curinga composto só pode ter one termos curinga e one ou mais termos de índice. { "pets.$**": 1, “familyName”: 1 }

Índices geoespaciais

Índices geoespaciais dão suporte a consultas em dados armazenados como objetos GeoJSON ou pares de coordenadas herdados. Você pode usar índices geoespaciais para melhorar o desempenho de consultas em dados geoespaciais ou executar determinadas consultas geoespaciais.

O Azure DocumentDB fornece dois tipos de índices geoespaciais:

  • Índices 2dsphere, que dão suporte a consultas que interpretam geometria em uma superfície esférica.
  • Índices 2d, que dão suporte a consultas que interpretam geometria em uma superfície plana.

Índices 2D

Há suporte para os índices 2D apenas no estilo de par de coordenadas herdado de armazenar dados geoespaciais.

Use o createIndex método com a opção 2d para criar um índice geoespacial no location campo.

db.places.createIndex({ "location": "2d"});

Limitações

  • Somente one o campo de localização pode fazer parte do 2d índice e apenas one outros campos não geoespaciais podem fazer parte do compound 2d índice db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1 })

Índices 2dsphere

2dsphere os índices dão suporte a consultas geoespaciais em uma esfera semelhante à Terra. Ele pode dar suporte a objetos GeoJSON ou pares de coordenadas herdados. 2dSphere os índices funcionam com o estilo GeoJSON de armazenamento de dados, se forem encontrados pontos herdados, ele será convertido em ponto GeoJSON.

Use o createIndex método com a opção 2dsphere para criar um índice geoespacial no location campo.

db.places.createIndex({ "location": "2dsphere"});

2dsphere os índices permitem a criação de índices em vários campos de dados geoespaciais e vários campos de dados não geoespaciais. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Limitações

  • Não há suporte para um índice composto usando um índice regular e um índice geoespacial. A criação de um dos índices geoespaciais levaria a erros.

    // Compound Regular & 2dsphere indexes are not supported yet
    db.collection.createIndex({a: 1, b: "2dsphere"})
    
    // Compound 2d indexes are not supported yet
    db.collection.createIndex({a: "2d", b: 1})
    
  • Polígonos com buracos não funcionam. Não há restrições para inserir um polígono com um buraco, embora $geoWithin a consulta falhe em cenários:

    1. Se a consulta em si tiver polígono com orifícios

      coll.find(
        {
            "b": {
                "$geoWithin": {
                    "$geometry": {
                        "coordinates": [
                            [
                                [ 0, 0], [0, 10], [10, 10],[10,0],[0, 0]
                            ],
                            [
                                [5, 5], [8, 5], [ 8, 8], [ 5, 8], [ 5, 5]
                            ]
                        ],
                        "type": "Polygon"
                    }
                }
            }
        })
      
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    2. Se houver algum documento não filtrado que tenha polígono com orifícios.

      [mongos] test> coll.find()
        [
          {
            _id: ObjectId("667bf7560b4f1a5a5d71effa"),
            b: {
              type: 'Polygon',
              coordinates: [
                [ [ 0, 0 ], [ 0, 10 ], [ 10, 10 ], [ 10, 0 ], [ 0, 0 ] ],
                [ [ 5, 5 ], [ 8, 5 ], [ 8, 8 ], [ 5, 8 ], [ 5, 5 ] ]
              ]
            }
          }
        ]
      // MongoServerError: $geoWithin currently doesn't support polygons with holes
      
    3. key o campo é obrigatório ao usar geoNear.

       [mongos] test> coll.aggregate([{ $geoNear: { $near: { "type": "Point", coordinates: [0, 0] } } }])
      
       // MongoServerError: $geoNear requires a 'key' option as a String
      

Próximas etapas