Compartilhar via


Gerenciar a indexação no Azure Cosmos DB for MongoDB

O Azure Cosmos DB for MongoDB permite usar a indexação para acelerar o desempenho das consultas. Este artigo mostra como gerenciar e otimizar índices para recuperar dados mais rápido e com mais eficiência.

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

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

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

Editar 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 no editor de política de indexação do Data Explorer:

Captura de tela do editor de política de indexação no Azure Cosmos DB for MongoDB.

Observação

Você não pode criar índices compostos usando o editor de política de indexação no Data Explorer.

Tipos de índice

Campo único

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

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

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

Captura de tela da adição de um índice de nome no editor de política 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 para MongoDB, use índices compostos em consultas que classificam vários campos ao mesmo tempo. Para consultas com vários filtros que não precisam ser classificados, crie vários índices de campo único em vez de um único índice composto para economizar nos custos de indexação.

Um índice composto ou índices de campo único para cada campo do índice composto resultam no mesmo desempenho ao filtrar consultas.

Índices compostos em campos aninhados não têm suporte por padrão devido a limitações com matrizes. Se um campo aninhado não tiver uma matriz, o índice funcionará conforme o esperado. Se um campo aninhado tiver uma matriz em qualquer ponto do caminho, esse valor será ignorado no índice.

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

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

O mesmo índice composto não funciona nesse 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 a funcionalidade 'EnableUniqueCompoundNestedDocs'.

Observação

Você não pode 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, de forma eficiente, vários campos ao mesmo tempo, 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, de forma eficiente, uma consulta com a ordem de classificação oposta em todos os campos. Aqui está um exemplo:

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

No entanto, a sequência dos caminhos no índice composto deve corresponder exatamente à consulta. Veja um exemplo de consulta que exigiria um índice composto adicional:

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

Índices de várias chaves

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

Índices geoespaciais

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

Este é um exemplo de criação de um índice geoespacial no campo ___location:

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

Índices de texto

O Azure Cosmos DB for MongoDB não dá suporte a índices de texto. Para consultas de pesquisa de texto em cadeias de caracteres, use a integração Pesquisa de IA do Azure com o Azure Cosmos DB.

Índices curinga

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

Veja parte de um documento de exemplo nessa coleção:

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

Veja 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 dessa coleção podem ter muitas propriedades diferentes. Para indexar todos os dados na matriz children, crie índices separados para cada propriedade ou um único índice curinga para toda a matriz children.

Criar um índice curinga

Use o comando a seguir para criar um índice curinga em quaisquer propriedades dentro de children:

db.coll.createIndex({"children.$**" : 1})
  • Ao contrário do MongoDB, os índices curinga podem dar suporte a vários campos em predicados de consulta. Não há diferença no desempenho das consultas 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

Indexando todas as propriedades

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

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

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

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

Observação

Se você estiver começando o desenvolvimento, inicie com um índice curinga em todos os campos. Essa abordagem simplifica o desenvolvimento e facilita a otimização das consultas.

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

Limitações

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

  • Composto

  • TTL

  • Exclusivo

  • Diferente do MongoDB, no Azure Cosmos DB for MongoDB não é possível usar índices curinga para:

  • Como 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 coringa que exclua vários campos específicos

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

Como alternativa, crie vários índices curinga.

Propriedades de índice

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

Índices exclusivos

Índices exclusivos ajudam a garantir que dois ou mais documentos não tenham o mesmo valor em campos indexados.

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

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 de 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 shard. A chave de shard deve ser o primeiro campo na definição do índice.

Execute os seguintes comandos para criar uma coleção fragmentada chamada coll (com university como chave de shard) e um índice exclusivo nos campos student_id e 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 cláusula "university":1 no exemplo anterior, verá a seguinte mensagem de erro:

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

Limitações

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

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

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 têm suporte por padrão devido a limitações com matrizes. Se o campo aninhado não tiver uma matriz, o índice funcionará conforme o esperado. Se o campo aninhado tiver uma matriz em qualquer parte do caminho, esse valor será ignorado no índice exclusivo, e a exclusividade não será mantida para esse valor.

Por exemplo, um índice exclusivo em people.tom.age funciona nesse caso porque não há 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 habilitado para sua conta de banco de dados habilitando a capacidade 'EnableUniqueCompoundNestedDocs'.

Índices TTL

Para permitir que documentos expirem em uma coleção, crie um índice de tempo de vida (TTL). Um índice TTL é um índice no campo _ts com um valor expireAfterSeconds.

Exemplo:

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

O comando anterior exclui quaisquer documentos na coleção db.coll que tenham sido modificados há mais de 10 segundos.

Observação

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

Acompanhar o progresso do índice

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

Veja alguns exemplos de como usar o comando currentOp para acompanhar o progresso de indexação:

  • Obter o progresso de indexação de uma coleção:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • Obter o progresso de indexação de todas as coleções em um banco de dados:

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

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

Exemplos de saída do progresso de índice

Os detalhes do progresso de indexação mostram o percentual de avanço da operação de índice atual. Veja exemplos do formato do documento de saída para diferentes estágios do progresso de indexação:

  • Uma operação de índice em uma coleção "foo" e banco de dados "bar" com 60% concluídos tem o seguinte documento de saída. O campo Inprog[0].progress.total mostra 100 como a porcentagem 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 acabou de começar em uma coleção "foo" e banco de dados "bar", o documento de saída poderá 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 inprogvazias.

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

Atualizações do í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 Background. Como as atualizações de índice usam Unidades de Solicitação (RUs) com prioridade menor que outras ações do 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 apenas depois que a transformação de índice é concluída. Durante a transformação, o mecanismo de consulta continua usando os índices existentes, mantendo desempenho de leitura semelhante ao anterior à alteração de indexação. Adicionar novos índices não traz risco de resultados de consulta incompletos ou divergentes.

Se você remover índices e executar imediatamente consultas que filtrem nesses índices removidos, os resultados poderão ser divergentes e incompletos até que a transformação de índice termine. O mecanismo de consulta não fornece resultados consistentes ou completos para consultas que filtrem em índices recém-removidos. A maioria dos desenvolvedores não remove índices e em seguida os consulta imediatamente, portanto essa situação é improvável.

Observação

Você pode acompanhar o progresso do índice.

reIndex comando

O comando reIndex recria todos os índices de uma coleção. Em casos raros, executar o comando reIndex pode corrigir o desempenho de consultas ou outros problemas de índice na sua coleção. Se estiver enfrentando problemas de indexação, tente recriar os índices com o comando reIndex.

Execute o comando reIndex usando a seguinte sintaxe:

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

Use a seguinte sintaxe para verificar se a execução do comando reIndex melhora o desempenho de consultas 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 de consultas, requiresReIndex será verdadeiro. Se reIndex não melhorar o desempenho de consultas, essa propriedade será omitida.

Migrando coleções com índices

Você só pode criar índices exclusivos quando a coleção não tiver documentos. Ferramentas populares de migração do MongoDB tentam criar índices exclusivos após importar os dados. Para contornar esse problema, crie manualmente as coleções e os índices exclusivos correspondentes em vez de deixar a ferramenta de migração tentar fazê-lo. É possível obter esse comportamento para mongorestore usando o sinalizador --noIndexRestore na linha de comando.

Indexação do MongoDB versão 3.2

Os recursos e padrões de indexação variam para contas do Azure Cosmos DB que usam a versão 3.2 do protocolo wire do 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 mostrará as principais diferenças em relação às versões 3.6 e posteriores.

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

Diferentemente das versões 3.6 e posteriores, o Azure Cosmos DB for MongoDB versão 3.2 indexa todas as propriedades por padrão. Use o comando a seguir para remover esses índices padrão de uma coleção (coll):

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

Depois de remover os índices padrão, adicione outros índices como nas versões 3.6 e posteriores.

Í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óximas etapas