Partilhar via


Gerenciar indexação no Azure Cosmos DB para MongoDB

O Azure Cosmos DB para MongoDB permite que você use a indexação para acelerar o desempenho da consulta. Este artigo mostra como gerenciar e otimizar índices para recuperação de dados mais rápida e melhor eficiência.

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

O servidor Azure Cosmos DB para MongoDB versão 3.6+ indexa automaticamente o _id campo e a chave de estilhaço (apenas em coleções fragmentadas). A API impõe a exclusividade do campo por chave de _id estilhaço.

A API para MongoDB funciona de forma diferente do Azure Cosmos DB para NoSQL, que indexa todos os campos por padrão.

Editando a política de indexação

Edite sua política de indexação no Data Explorer no portal do Azure. Adicione índices de campo único e curinga do editor de política de indexação no Data Explorer:

Captura de ecrã do editor de políticas de indexação no Azure Cosmos DB para MongoDB.

Nota

Não é possível criar índices compostos usando o editor de políticas de indexação no Data Explorer.

Tipos de índice

Campo único

Crie um índice em qualquer campo. A ordem de classificação do índice de campo único não importa. Use o seguinte comando para criar um índice no campo name:

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

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

Captura de ecrã a mostrar a adição de um índice de nomes no editor de políticas de indexação.

Uma consulta usa vários índices de campo único, quando disponíveis. Crie até 500 índices de campo único por coleção.

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

Na API do MongoDB, use índices compostos com consultas que classificam vários campos ao mesmo tempo. Para consultas com vários filtros que não precisam classificar, crie vários índices de campo único em vez de um índice composto para economizar nos custos de indexação.

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

Índices compostos em campos aninhados não são suportados por padrão devido a limitações com matrizes. Se um campo aninhado não tiver uma matriz, o índice funcionará como pretendido. Se um campo aninhado tiver uma matriz em qualquer lugar do caminho, esse valor será ignorado no índice.

Por exemplo, um índice composto que contém people.dylan.age funciona neste caso porque não há nenhuma matriz no caminho:

{
  "people": {
    "dylan": {
      "name": "Dylan",
      "age": "25"
    },
    "reed": {
      "name": "Reed",
      "age": "30"
    }
  }
}

O mesmo índice composto não funciona neste caso porque há uma matriz no caminho:

{
  "people": [
    {
      "name": "Dylan",
      "age": "25"
    },
    {
      "name": "Reed",
      "age": "30"
    }
  ]
}

Habilite esse recurso para sua conta de banco de dados habilitando o recurso 'EnableUniqueCompoundNestedDocs'.

Nota

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

O comando a seguir cria um índice composto nos campos name e age:

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

Você pode usar índices compostos para classificar eficientemente em vários campos de uma só vez, conforme mostrado no exemplo a seguir:

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

Você também pode usar o índice composto anterior para classificar eficientemente uma consulta com a ordem de classificaçã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 deve corresponder exatamente à consulta. Aqui está um exemplo de uma consulta que exigiria um índice composto extra:

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

Índices multichave

O Azure Cosmos DB cria índices de várias chaves para indexar conteúdo em matrizes. Se você indexar um campo com um valor de matriz, o Azure Cosmos DB indexará automaticamente cada elemento na matriz.

Índices geoespaciais

Muitos operadores geoespaciais se beneficiam de índices geoespaciais. O Azure Cosmos DB para MongoDB dá suporte a 2dsphere índices. A API ainda não suporta 2d índices.

Aqui está um exemplo de criação de um índice geoespacial no location campo:

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

Índices de texto

O Azure Cosmos DB para MongoDB não oferece suporte a índices de texto. Para consultas de pesquisa de texto em cadeias de caracteres, use a integração do Azure AI Search com o Azure Cosmos DB.

Índices curinga

Use índices curinga para dar suporte a consultas em campos desconhecidos. Imagine uma coleção que tem dados sobre famílias.

Aqui está parte de um documento de exemplo nessa coleção:

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

Aqui está outro exemplo com um conjunto diferente de propriedades em children:

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

Os documentos desta coleção podem ter muitas propriedades diferentes. Para indexar todos os dados na children matriz, crie índices separados para cada propriedade ou crie um índice curinga para toda children a matriz.

Criar um índice curinga

Use o seguinte comando para criar um índice curinga em qualquer propriedade dentro de children:

db.coll.createIndex({"children.$**" : 1})
  • Ao contrário do MongoDB, os índices curinga podem suportar múltiplos campos nos predicados de consulta. Não há diferença no desempenho da consulta se você usar um único índice curinga em vez de criar um índice separado para cada propriedade.

Crie os seguintes tipos de índice usando a sintaxe curinga:

  • Campo único
  • Geoespacial

Indexação de todas as propriedades

Crie um índice curinga em todos os campos com o seguinte comando:

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

Crie índices curinga usando o Data Explorer no portal do Azure:

Adicionar índice curinga no editor de políticas de indexação

Nota

Se você está apenas começando o desenvolvimento, comece com um índice curinga em todos os campos. Essa abordagem simplifica o desenvolvimento e facilita a otimização de consultas.

Documentos com muitos campos podem ter uma alta taxa de Unidade de Solicitação (RU) para gravações e atualizações. Se você tiver uma carga de trabalho de gravação pesada, use caminhos indexados individualmente em vez de curingas.

Limitações

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

  • Compostos

  • TTL

  • Exclusivo

  • Ao contrário do MongoDB, no Azure Cosmos DB para MongoDB você não pode usar índices curinga para:

  • Criar um índice curinga que inclui vários campos específicos

    db.coll.createIndex(
      { "$**" : 1 },
      { "wildcardProjection " :
        {
          "children.givenName" : 1,
          "children.grade" : 1
        }
      }
    )
    
  • Criar um índice de carateres universais que exclui vários campos específicos

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

Como alternativa, crie vários índices curinga.

Propriedades do índice

As operações a seguir são comuns para contas que usam o protocolo wire versão 4.0 e versões anteriores. Saiba mais sobre índices e propriedades indexadas suportados.

Índices exclusivos

Os índices exclusivos ajudam a garantir que dois ou mais documentos não tenham o mesmo valor para campos indexados.

Execute o seguinte comando para criar um índice exclusivo no student_id campo:

db.coll.createIndex( { "student_id" : 1 }, {unique:true} )

{
  "_t" : "CreateIndexesResponse",
  "ok" : 1,
  "createdCollectionAutomatically" : false,
  "numIndexesBefore" : 1,
  "numIndexesAfter" : 4
}

Para coleções fragmentadas, forneça a chave shard (partição) para criar um índice exclusivo. Todos os índices exclusivos em uma coleção fragmentada são índices compostos e um dos campos é a chave de estilhaço. A chave de estilhaço deve ser o primeiro campo na definição do índice.

Execute os seguintes comandos para criar uma coleção fragmentada chamada coll (com university a tecla de estilhaço) e um índice exclusivo nos student_id campos and university :

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

Se você omitir a "university":1 cláusula no exemplo anterior, você verá a seguinte mensagem de erro:

cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }

Limitações

Crie índices exclusivos enquanto a coleção estiver vazia.

As contas do Azure Cosmos DB para MongoDB com backup contínuo não oferecem suporte à criação de um índice exclusivo para uma coleção existente. Para essa conta, índices únicos devem ser criados junto com a criação da coleção, o que deve e só pode ser feito usando os comandos da extensão create collection extension commands.

db.runCommand({customAction:"CreateCollection", collection:"coll", shardKey:"student_id", indexes:[
{key: { "student_id" : 1}, name:"student_id_1", unique: true}
]});

Índices exclusivos em campos aninhados não são suportados por padrão devido a limitações com matrizes. Se o campo aninhado não tiver uma matriz, o índice funcionará como pretendido. Se o campo aninhado tiver uma matriz em qualquer lugar do caminho, esse valor será ignorado no índice exclusivo e a exclusividade não será preservada para esse valor.

Por exemplo, um índice exclusivo em people.tom.age funciona neste caso porque não há nenhuma matriz no caminho:

{
  "people": {
    "tom": {
      "age": "25"
    },
    "mark": {
      "age": "30"
    }
  }
}

Mas não funciona neste caso porque há uma matriz no caminho:

{
  "people": {
    "tom": [
      {
        "age": "25"
      }
    ],
    "mark": [
      {
        "age": "30"
      }
    ]
  }
}

Esse recurso pode ser ativado para sua conta de banco de dados ativando o recurso 'EnableUniqueCompoundNestedDocs'.

Índices TTL

Para permitir que os documentos expirem em uma coleção, crie um índice TTL (time-to-live). Um índice TTL é um índice do campo _ts com valor expireAfterSeconds.

Exemplo:

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

O comando anterior exclui todos os documentos da db.coll coleção que foram modificados há mais de 10 segundos.

Nota

O campo _ts é específico do Azure Cosmos DB e não pode ser acessado a partir de clientes MongoDB. É uma propriedade reservada (sistema) que contém o carimbo de data/hora da última modificação do documento.

Acompanhe o progresso do índice

A versão 3.6+ do Azure Cosmos DB para MongoDB dá suporte ao comando para acompanhar o progresso do currentOp() índice em uma instância de banco de dados. Este comando retorna um documento com informações sobre operações em andamento em uma instância de banco de dados. Use o currentOp comando para rastrear todas as operações em andamento no MongoDB nativo. No Azure Cosmos DB para MongoDB, esse comando rastreia apenas a operação de índice.

Aqui estão alguns exemplos de como usar o comando para acompanhar o progresso do currentOp índice:

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

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

    db.currentOp({"command.$db": <databaseName>})
    
  • Obtenha o progresso do índice para todos os bancos de dados e coleções em uma conta do Azure Cosmos DB:

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

Exemplos de resultados de progresso do índice

Os detalhes de progresso do índice mostram a porcentagem de progresso para a operação de índice atual. Aqui estão exemplos do formato do documento de saída para diferentes estágios do progresso do índice:

  • Uma operação de índice em um banco de dados "foo" collection e "bar" 60% concluída tem o seguinte documento de saída. O Inprog[0].progress.total campo mostra 100 como a porcentagem de conclusão do alvo.

    {
      "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 acabou de ser iniciada em um banco de dados "foo" collection e "bar", o documento de saída pode mostrar 0% de progresso até atingir um nível mensurá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 termina, o documento de saída mostra operações vazias inprog .

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

Atualizações de índice em segundo plano

As atualizações de índice sempre são executadas em segundo plano, independentemente do valor definido para a propriedade de índice em segundo plano . Como as atualizações de índice usam Unidades de Solicitação (RUs) com prioridade mais baixa do que outras ações de banco de dados, as alterações de índice não causam tempo de inatividade para gravações, atualizações ou exclusões.

Adicionar um novo índice não afeta a disponibilidade de leitura. As consultas usam novos índices somente após a conclusão da transformação do índice. Durante a transformação, o mecanismo de consulta continua usando índices existentes, para que você veja um desempenho de leitura semelhante ao de antes de iniciar a alteração de indexação. Adicionar novos índices não corre o risco de resultados de consulta incompletos ou inconsistentes.

Se você remover índices e executar imediatamente consultas que filtram esses índices descartados, os resultados poderão ser inconsistentes e incompletos até que a transformação do índice seja concluída. O mecanismo de consulta não fornece resultados consistentes ou completos para consultas que filtram índices recém-removidos. A maioria dos desenvolvedores não descarta índices e, em seguida, consultá-los imediatamente, portanto, essa situação é improvável.

reIndex comando

O reIndex comando recria todos os índices em uma coleção. Em casos raros, a execução do comando pode corrigir o desempenho da reIndex consulta ou outros problemas de índice em sua coleção. Se você estiver enfrentando problemas de indexação, tente recriar os índices com o reIndex comando.

Execute o reIndex comando usando a seguinte sintaxe:

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

Use a sintaxe a seguir para verificar se a execução do comando melhora o desempenho da reIndex consulta em 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, requiresReIndex é true. Se reIndex não melhorar o desempenho da consulta, essa propriedade será omitida.

Migrar coleções com índices

Só é possível criar índices exclusivos quando a coleção não tiver documentos. As ferramentas de migração populares do MongoDB tentam criar índices exclusivos após a importação dos dados. Para contornar esse problema, crie manualmente as coleções correspondentes e índices exclusivos em vez de deixar a ferramenta de migração tentar. Você obtém esse comportamento para mongorestore usando o --noIndexRestore sinalizador na linha de comando.

Indexação para MongoDB versão 3.2

Os recursos e padrões de indexação diferem para contas do Azure Cosmos DB que usam a versão 3.2 do protocolo de conexão MongoDB. Verifique a versão da sua conta em feature-support-36.md#protocol-support e atualize para a versão 3.6 em upgrade-version.md.

Se você estiver usando a versão 3.2, esta seção destaca as principais diferenças das versões 3.6 e posteriores.

Descartando índices padrão (versão 3.2)

Ao contrário das versões 3.6 e posteriores, o Azure Cosmos DB para MongoDB versão 3.2 indexa todas as propriedades por padrão. Use o seguinte comando para descartar esses índices padrão para uma coleção (coll):

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

Depois de descartar os índices padrão, adicione mais índices como faz na versão 3.6 e posterior.

Índices compostos (versão 3.2)

Os índices compostos fazem referência a vários campos em um documento. Para criar um índice composto, atualize para a versão 3.6 ou 4.0 em upgrade-version.md.

Índices curinga (versão 3.2)

Para criar um índice curinga, atualize para a versão 4.0 ou 3.6 em upgrade-version.md.

Próximos passos