Gerir a indexação na API do Azure Cosmos DB para o MongódB

APLICA-SE A: API DB do Azure Cosmos para MongóDB

A API do Azure Cosmos DB para o MongoDB tira partido das principais funcionalidades de gestão de índices do Azure Cosmos DB. Este artigo foca-se em como adicionar índices com a API do Azure Cosmos DB para o MongoDB. Os índices são estruturas de dados especializadas que fazem com que a consulta dos seus dados seja aproximadamente uma ordem de magnitude mais rápida.

Indexação para a versão 3.6 e superior do servidor MongoDB

A API do API do Azure Cosmos DB para a versão 3.6 do servidor MongódB indexa automaticamente o campo e a chave de fragmento (apenas em coleções de _id fragmentos). A API impõe automaticamente a exclusivaidade do _id campo por chave de fragmento.

A API para a Mongólia tem um comportamento diferente do Azure Cosmos DB SQL API, que indexa todos os campos por predefinição.

Editar política de indexação

Recomendamos que edite a sua política de indexação no Explorador de Dados no portal do Azure. . Pode adicionar índices de campo único e de cartões individuais a partir do editor de política de indexação no Explorador de Dados:

Editor de política de indexação

Nota

Não é possível criar índices compostos através do editor de política de indexação no Explorador de Dados.

Tipos de índice

Campo único

Pode criar índices em qualquer campo único. A ordenação do índice de campo único não é importante. O seguinte comando cria um índice no name campo:

db.coll.createIndex({name:1})

Pode criar o mesmo índice de campo único name no portal do Azure:

Adicionar índice de nomes no editor de política de indexação

Uma consulta utiliza múltiplos índices de campo únicos sempre que disponíveis. Pode criar até 500 índices de campo únicos por coleção.

Índices compostos (versão 3.6+) do servidor MongoDB

Na API para a Mongólia, são necessários índices compostos se a consulta necessitar da capacidade de ordenar em múltiplos campos ao mesmo tempo. Para consultas com múltiplos filtros que não precisam de ordenar, crie múltiplos índices de campo único em vez de um índice composto para poupar nos custos de indexação.

Um índice composto ou índices de campo único para cada campo no índice composto resultarão no mesmo desempenho para filtragem em consultas.

Nota

Não é possível criar índices compostos em propriedades ou matrizes aninhadas.

O comando seguinte cria um índice composto nos campos nameage e:

db.coll.createIndex({name:1,age:1})

Pode utilizar índices compostos para ordenar eficazmente em múltiplos campos de uma só vez, conforme apresentado no exemplo seguinte:

db.coll.find().sort({name:1,age:1})

Também pode utilizar o índice composto anterior para ordenar eficazmente numa consulta com a ordem de ordenação oposta em todos os campos. Eis um exemplo:

db.coll.find().sort({name:-1,age:-1})

No entanto, a sequência dos caminhos no índice composto tem de corresponder exatamente à consulta. Eis um exemplo de uma consulta que necessitaria de um índice composto adicional:

db.coll.find().sort({age:1,name:1})

Nota

Os índices compostos só são utilizados em consultas que ordenam os resultados. Para consultas que têm múltiplos filtros que não precisam de ordenar, crie índices de campo único múltiplos.

Índices de múltiplas secções

O Azure Cosmos DB cria índices de váriaskey para indexar conteúdo armazenado em matrizes. Se indexar um campo com um valor de matriz, o Azure Cosmos DB indexa automaticamente todos os elementos da matriz.

Índices geoespaciais

Muitos operadores geoespaciais irão beneficiar de índices geoespaciais. Atualmente, a API do Azure Cosmos DB para mongólia suporta 2dsphere índices. A API ainda não suporta 2d índices.

Eis um exemplo da criação de um índice geoespacial no location campo:

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

Índices de texto

A API do API do Azure Cosmos DB para o MongoDB não suporta atualmente índices de texto. Para consultas de pesquisa de texto em cadeias, deve utilizar a integração da Pesquisa Cognitiva do Azure com o Azure Cosmos DB.

Índices de cartões versões

Pode utilizar índices de cartões virais para suportar consultas em campos desconhecidos. Imaginemos que tem uma coleção que tem dados sobre famílias.

Eis parte de um documento de exemplo na coleção:

"children": [
   {
     "firstName": "Henriette Thaulow",
     "grade": "5"
   }
]

Eis outro exemplo, desta vez com um conjunto de propriedades ligeiramente diferente em children :

"children": [
    {
     "familyName": "Merriam",
     "givenName": "Jesse",
     "pets": [
         { "givenName": "Goofy" },
         { "givenName": "Shadow" }
         ]
   },
   {
     "familyName": "Merriam",
     "givenName": "John",
   }
]

Nesta coleção, os documentos podem ter muitas propriedades possíveis diferentes. Se quiser indexar todos os dados na matriz, tem duas opções: criar índices separados para cada propriedade individual ou criar um índice de um tipo selvagem para a matriz childrenchildren inteira.

Criar um índice de wildcard

O comando seguinte cria um índice de tabelas wildcard em todas as propriedades dentro de children :

db.coll.createIndex({"children.$**" : 1})

Ao contrário do que acontece no Mongótipo, os índices de carateres wildcard podem suportar múltiplos campos em predicados de consulta. Não haverá uma diferença no desempenho da consulta se utilizar um único índice de um tipo selvagem em vez de criar um índice separado para cada propriedade.

Pode criar os seguintes tipos de índice utilizando a sintaxe de um tipo selvagem:

  • Campo único
  • Geoespacial

Indexar todas as propriedades

Eis como pode criar um índice de um tipo selvagem em todos os campos:

db.coll.createIndex( { "$**" : 1 } )

Também pode criar índices com o Explorador de Dados no portal do Azure:

Adicionar índice de um postal ao editor de política de indexação

Nota

Se está apenas a começar o desenvolvimento, recomendamos vivamente que ter tudo a que seja iniciado com um índice de cartões wildcard em todos os campos. Isto pode simplificar o desenvolvimento e facilitar a otimização de consultas.

Os documentos com muitos campos poderão ter um custo de Unidade de Pedido (RU) elevado para escritas e atualizações. Por essa razão, se tiver uma carga de trabalho com muita escrita, deve optar por indexar individualmente os caminhos em vez de utilizar índices decartais.

Limitações

Os índices de características wildcard não suportam nenhum dos seguintes tipos de índice ou propriedades:

  • Composto
  • TTL
  • Exclusivo

Ao contrário do que acontece no MongoDB,na API do Azure Cosmos DB para mongólia não pode utilizar índices de carateres wildcard para:

  • Criar um índice de um tipo wildcard que inclui múltiplos campos específicos

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection " :
            {
               "children.givenName" : 1,
               "children.grade" : 1
            }
        }
    )
    
  • Criar um índice de um tipo wildcard que exclui múltiplos campos específicos

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection" :
            {
               "children.givenName" : 0,
               "children.grade" : 0
            }
        }
    )
    

Como alternativa, pode criar múltiplos índices de cartões virais.

Propriedades do índice

As seguintes operações são comuns às contas que servem a versão 4.0 do Wire Protocol e contas que servem versões anteriores. Pode saber mais sobre os índices suportados e as propriedades indexadas.

Índices exclusivos

Os índices exclusivos são úteis para impor que dois ou mais documentos não contenham o mesmo valor para campos indexados.

Importante

Os índices exclusivos só podem ser criados quando a coleção estiver vazia (não contém documentos).

O comando seguinte cria um índice exclusivo no student_id campo:

globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 4
}

Para coleções de fragmentos, tem de fornecer a chave de fragmento (partição) para criar um índice exclusivo. Por outras palavras, todos os índices exclusivos numa coleção de fragmentos são índices compostos em que um dos campos é a chave de partição.

Os seguintes comandos criam uma coleção sombrida (a chave de fragmento é ) com um coll índice exclusivo nos campos universitystudent_iduniversity e:

globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
    "_t" : "ShardCollectionResponse",
    "ok" : 1,
    "collectionsharded" : "test.coll"
}
globaldb:PRIMARY> db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 3,
    "numIndexesAfter" : 4
}

No exemplo anterior, omitir a "university":1 cláusula devolve um erro com a seguinte mensagem:

não é possível criar um índice exclusivo acima de {student_id : 1.0} com padrão-chave de fragmentos { universidade : 1,0 }

Índices TTL

Para ativar a expiração do documento numa coleção específica, tem de criar um índice de tempo de vida (TTL). Um índice TTL é um índice no _ts campo com um expireAfterSeconds valor.

Exemplo:

globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})

O comando anterior elimina todos os documentos da coleção que não foram db.coll modificados nos últimos 10 segundos.

Nota

O _ts é específico do Azure Cosmos DB e não é acessível a partir de clientes MongódB. É uma propriedade reservada (sistema) que contém o carimbo de data/hora da última modificação do documento.

Controlar o progresso dos índices

A versão 3.6+ da API da API do Azure Cosmos DB para Mongólia suporta o comando para controlar o progresso do índice numa currentOp() instância de base de dados. Este comando devolve um documento que contém informações sobre operações em curso numa instância de base de dados. Utilize o comando currentOp para controlar todas as operações em curso no Mongólia nativo. Na API do API do Azure Cosmos DB para o MongoDB, este comando só suporta o controlo da operação de índice.

Eis alguns exemplos que mostram como utilizar o comando para currentOp controlar o progresso do índice remissivo:

  • Obter o progresso do índice de uma coleção:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Obter o progresso do índice para todas as coleções numa base de dados:

    db.currentOp({"command.$db": <databaseName>})
    
  • Obter o progresso do índice para todas as bases de dados e coleções numa conta do Azure Cosmos:

    db.currentOp({"command.createIndexes": { $exists : true } })
    

Exemplos de resultados do progresso do índice

Os detalhes de progresso do índice mostram a percentagem de progresso da operação de índice atual. Eis um exemplo que mostra o formato do documento de saída para diferentes fases do progresso do índice:

  • Uma operação de índice numa coleção "foo" e base de dados com "barra" 60% concluída terá o seguinte documento de saída. O Inprog[0].progress.total campo mostra 100 como a percentagem de conclusão de destino.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 60 %",
                  "progress" : {
                          "done" : 60,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
          "ok" : 1
    }
    
  • Se uma operação de índice tiver começado numa coleção "foo" e numa base de dados de "barra", o documento de saída poderá mostrar um progresso de 0% até atingir um nível quadrível.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 0 %",
                  "progress" : {
                          "done" : 0,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
         "ok" : 1
    }
    
  • Quando a operação de índice em curso terminar, o documento de saída mostra operações inprog vazias.

    {
        "inprog" : [],
        "ok" : 1
    }
    

Atualizações de índice em segundo plano

Independentemente do valor especificado para a propriedade Índice de fundo, as atualizações de índices são sempre feitas em segundo plano. Uma vez que as atualizações de índices consomem Unidades de Pedido (RUs) numa prioridade mais baixa do que outras operações de base de dados, as alterações ao índice não resultarão em tempo de inatividade para escritas, atualizações ou eliminações.

Não existe impacto na disponibilidade de leitura ao adicionar um novo índice. As consultas utilizarão novos índices apenas quando a transformação do índice estiver concluída. Durante a transformação do índice, o motor de consulta continuará a utilizar os índices existentes, pelo que irá observar um desempenho de leitura semelhante durante a transformação de indexação ao que tinha observado antes de iniciar a alteração da indexação. Ao adicionar novos índices, também não existe risco de resultados de consulta incompletos ou inconsistentes.

Ao remover índices e imediatamente executar consultas, os filtros nos índices retirados podem ser inconsistentes e incompletos até a transformação de índice terminar. Se remover índices, o motor de consulta não fornece resultados consistentes ou completos quando as consultas filtram estes índices removidos. A maioria dos programadores não larga os índices e, em seguida, tenta consulta-los de imediato, pelo que, na prática, esta situação é improvável.

Nota

Pode controlar o progresso dos índices.

Comando ReIndex

O reIndex comando irá recriar todos os índices numa coleção. Em alguns casos raros, o desempenho da consulta ou outros problemas de índice remissário na sua coleção podem ser resolvidos através da execução do reIndex comando. Se estiver a ter problemas com a indexação, recriar os índices com o reIndex comando é uma abordagem recomendada.

Pode executar o reIndex comando através da seguinte sintaxe:

db.runCommand({ reIndex: <collection> })

Pode utilizar a sintaxe abaixo para verificar se executar o comando reIndex melhoraria o desempenho da consulta na sua coleção:

db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})

Saída de exemplo:

{
        "database" : "myDB",
        "collection" : "myCollection",
        "provisionedThroughput" : 400,
        "indexes" : [
                {
                        "v" : 1,
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                },
                {
                        "v" : 1,
                        "key" : {
                                "b.$**" : 1
                        },
                        "name" : "b.$**_1",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                }
        ],
        "ok" : 1
}

Se reIndex melhorar o desempenho da consulta, requer reIndex seja verdadeiro. Se reIndex não melhorar o desempenho da consulta, esta propriedade será omitida.

Migrar coleções com índices

Atualmente, só pode criar índices exclusivos quando a coleção não contiver documentos. As ferramentas de migração populares da Mongólia tentam criar os índices exclusivos após importar os dados. Para contornar este problema, pode criar manualmente as coleções correspondentes e índices exclusivos em vez de permitir que a ferramenta de migração tente. (Pode atingir este comportamento ao mongorestore utilizar o --noIndexRestore sinalizador na linha de comandos.)

Indexação para a versão 3.2 do MongoDB

As funcionalidades de indexação disponíveis e as predefinições são diferentes para as contas do Azure Cosmos que são compatíveis com a versão 3.2 do protocolo de fios MongoDB. Pode verificar a versão da sua conta e atualizar para a versão 3.6.

Se estiver a utilizar a versão 3.2, esta secção esboçou as principais diferenças com as versões 3.6+.

Largar índices predefinido (versão 3.2)

Ao contrário das versões 3.6+ da API do Azure Cosmos DB para mongólia, a versão 3.2 indexa todas as propriedades por predefinição. Pode utilizar o seguinte comando para largar estes índices predefinido de uma coleção ( coll ):

> db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }

Após largar os índices predefinido, pode adicionar mais índices como faria na versão 3.6+.

Índices compostos (versão 3.2)

Os índices compostos têm referências a múltiplos campos de um documento. Se pretender criar um índice composto, atualize para a versão 3.6 ou 4.0.

Índices de wildcard (versão 3.2)

Se quiser criar um índice de um tipo selvagem, atualize para a versão 4.0 ou 3.6.

Passos seguintes

  • Indexação no Azure Cosmos DB
  • Expirar dados no Azure Cosmos DB automaticamente com tempo de vida
  • Para saber mais sobre a relação entre partição e indexação, consulte o artigo Consulta de um contentor do Azure Cosmos.
  • Está a tentar planear a capacidade de uma migração para o Azure Cosmos DB? Pode utilizar as informações sobre o seu cluster de bases de dados existente para o planeamento de capacidade.
    • Se tudo o que sabe é o número de vcores e servidores no seu cluster de bases de dados existente, leia sobre a estimativa das unidades de pedidos através de vCores ou vCPUs
    • Se conhecer taxas de pedidos típicas para a sua carga de trabalho da base de dados atual, leia sobre a estimativa das unidades de pedido utilizando o planeador de capacidade do Azure Cosmos DB