Partilhar via


Gerir a indexação no Azure DocumentDB

Os índices são estruturas que melhoram a velocidade de recuperação de dados ao proporcionar acesso rápido aos campos numa coleção. Funcionam criando um conjunto ordenado de ponteiros para dados, muitas vezes baseado em campos-chave. O Azure DocumentDB utiliza índices em múltiplos contextos, incluindo query push down, restrições únicas e sharding.

Importante

O campo "_id" é o único campo indexado por defeito e o tamanho máximo do campo pode ser 2 KB. Recomenda-se adicionar índices adicionais baseados em filtros de consulta e predicados para otimizar o desempenho.

Tipos de índice

Para simplificar, consideremos um exemplo de uma aplicação de blog com a seguinte configuração:

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

Esta aplicação de exemplo armazena artigos como documentos com a seguinte estrutura. Todos os exemplos citados utilizam ainda a estrutura desta 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

Os índices de campo único armazenam informação de um único campo numa coleção. A ordem de classificação do índice de campo único não importa. _id o campo mantém-se indexado por defeito.

O Azure DocumentDB suporta a criação de índice no seguinte

  • Campos de documento de topo.
  • Documento incorporado.
  • Campos dentro do documento incorporado.

O comando seguinte cria um único índice de campo no campo author e o comando seguinte cria-o num campo firstNameembutido .

use cosmicworks

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

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

Uma consulta pode usar múltiplos índices de campo único quando disponíveis.

Observação

O Azure DocumentDB permite criar um máximo de 64 índices numa coleção. Dependendo do escalão, podemos planear a extensão de até 300 índices mediante pedido.

Índices compostos

Os índices compostos melhoram o desempenho da base de dados ao permitir uma consulta e ordenação eficientes com base em múltiplos campos dentro dos documentos. Esta otimização reduz a necessidade de digitalizar coleções inteiras, acelerando a recuperação e organização dos dados.

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

use cosmicworks

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

Order dos campos afetam a seletividade ou 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 dentro de 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

  • Os índices parciais não suportam ORDER BY ou UNIQUE, a menos que o filtro os qualifique.

Índices de texto

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

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

use cosmicworks;

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

Observação

Embora possa definir apenas um índice de texto por coleção, o Azure DocumentDB permite-lhe criar índices de texto em combinação de vários campos para realizar pesquisas de texto em diferentes campos dos 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 o seu comportamento. Por exemplo, pode especificar o idioma para análise de texto, definir pesos para priorizar certos campos e configurar pesquisas que não fazem distinção entre maiúsculas e minúsculas. Aqui está um exemplo de criação de um índice de texto com opções:

  • Crie um índice para suportar a pesquisa tanto no campo title como no campo content com suporte ao idioma inglês. Além disso, atribui pesos mais altos ao title campo para o priorizar nos resultados de 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 realiza uma consulta de pesquisa de texto com o termo "DocumentDB", a pontuação de cada documento da coleção será calculada com base na presença e frequência do termo tanto nos campos "título" como no "conteúdo", dando maior importância ao campo "título" devido ao seu maior peso.

Realize uma pesquisa de texto usando um índice de texto

Depois de criado o índice de texto, pode realizar pesquisas de texto usando o operador "texto" nas suas consultas. O operador de texto pega numa string de pesquisa e compara-a com o índice de texto para encontrar documentos relevantes.

  • Faça uma pesquisa de texto pela expressão DocumentDB.

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

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

Limitações

  • Apenas um índice de texto pode ser definido em uma coleção.
  • As operações de ordenação não podem usar a ordem do índice de texto no MongoDB.
  • O Hint() não é suportado em combinação com uma consulta usando $text expressão.
  • Os índices de texto podem ser relativamente grandes, consumindo espaço de armazenamento significativo em comparação com outros tipos de índice.

Índices de WildCard

Índice num único campo, indexa todos os caminhos abaixo do field , excluindo outros campos que estejam no mesmo nível. Por exemplo, para o seguinte documento de exemplo

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

Criar um índice em { "pets.$**": 1 } cria um índice nos detalhes e propriedades dos subdocumentos, mas não cria um índice em "familyName".

Limitações

  • Os índices wildcard não suportam índices únicos.
  • Os índices curinga não suportam push downs de ORDER BY a menos que o filtro inclua apenas caminhos presentes no índice curinga (uma vez que não indexam elementos indefinidos)
  • Um índice de curinga composto só pode ter um one termo curinga e one ou mais termos de índice. { "pets.$**": 1, “familyName”: 1 }

Índices geoespaciais

Índices geoespaciais suportam consultas em dados armazenados como objetos GeoJSON ou pares de coordenadas legados. Pode usar índices geoespaciais para melhorar o desempenho de consultas em dados geoespaciais ou para executar certas consultas geoespaciais.

O Azure DocumentDB fornece dois tipos de índices geoespaciais:

  • 2dsphere Indexes, que suportam consultas que interpretam geometria numa esfera.
  • Índices 2D, que suportam consultas que interpretam geometria numa superfície plana.

índices 2D

Os índices 2D são suportados apenas com o estilo antigo de pares de coordenadas para armazenar dados geoespaciais.

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

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

Limitações

  • Apenas 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 suportam consultas geoespaciais numa esfera semelhante à da Terra. Pode suportar tanto objetos GeoJSON como pares de coordenadas legados. 2dSphere os índices funcionam com o estilo GeoJSON de armazenar dados; se forem encontrados pontos legados, converter-se-ia em ponto GeoJSON.

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

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

2dsphere Os índices permitem criar índices em múltiplos campos de dados geoespaciais e múltiplos não geoespaciais. db.places.createIndex({ "location": "2d", "non-geospatial-field": 1 / -1, ... "more non-geospatial-field": 1 / -1 })

Limitações

  • Um índice composto usando um índice regular e um índice geoespacial não é suportado. Criar qualquer 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. Inserir um Polígono com buraco não é restrito, embora $geoWithin as consultas falhem em cenários:

    1. Se a própria consulta tiver polígono com buracos

      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 sem filtros que tenha polígonos com buracos.

      [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 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óximos passos