Wildcard Indexes com MongoDB 4.2
Tags: mongodb, nosql, indexes, performance
Published: 2019-08-14 14:55:50

---
title: Wildcard Indexes com MongoDB 4.2
published: true
description: Um pouco sobre o novo tipo de índice do MongoDB
tags: mongodb, nosql, indexes, performance
cover_image: https://thepracticaldev.s3.amazonaws.com/i/n7w6vxz0x8a6wj2yuexi.png
---

Fala pessoALL, aproveitando a liberação da versão GA do MongoDB 4.2, vou mostrar um pouquinho de um dos recursos que achei bem interessantes para na questão de modelagem e performance, um novo tipo de índice: o Wildcard index.

Como o MongoDB suporta um schemas dinâmicos, nossas aplicações podem fazer queries utilizando campos onde os nomes desses campos sejam desconhecidos ou até mesmo em campos opcionais. Até a versão 4.0 nós tínhamos duas maneiras de fazer isso: criando um índice para cada um desses campos, porém, precisávamos conhecer cada um deles, ou criar algo parecido com um dicionário com chaves e valores, o que ficaria "feio" e parecido com isso:

```json
{
  "k": "nome do atributo",
  "v": "valor do atributo"
}
```

O Wildcard Index vem pra nos auxiliar quando temos tanto campos com schema "fixo", ou o que eu acho mais bacana, quando temos campos com schema dinâmico. Vou dar um exemplo de com a base de candidatos de eleições no Brasil e fazer alguns testes de performance utilizando esse tipo de índice. Vejamos um exemplo de documento:

```json
{
    "_id" : ObjectId("5d126803044a9b1399ba41e7"),
    "personalInformation" : {
        "maritalStatus" : [ 
            {
                "year" : 2018,
                "code" : 1,
                "description" : "SOLTEIRO(A)"
            }
        ],
        "schooling" : [ 
            {
                "year" : 2018,
                "code" : 8,
                "description" : "SUPERIOR COMPLETO"
            }
        ],
        "emailAddresses" : [ 
            {
                "year" : 2018,
                "email" : "gpm.guimaraes.adv@gmail.com"
            }
        ],
        "birth" : {
            "date" : ISODate("1987-04-13T00:00:00.000Z"),
            "city" : "RIO DE JANEIRO",
            "cityCode" : -3,
            "state" : "RJ"
        },
        "voterRegistration" : "133364270353",
        "nationality" : "BRASILEIRA NATA",
        "occupation" : [ 
            {
                "year" : 2018,
                "code" : 257,
                "description" : "EMPRESARIO"
            }
        ],
        "name" : "HIPOLITO LUIS NUNEZ DOMARCO NETO",
        "gender" : "MASCULINO",
        "race" : "BRANCA",
        "document" : "09866446760",
        "socialName" : "#NULO#"
    },
    "electionInformation" : [ 
        {
            "year" : 2018,
            "state" : "RJ",
            "role" : {
                "code" : 6,
                "description" : "DEPUTADO FEDERAL"
            },
            "politicalParty" : {
                "legend" : "PMN / AVANTE",
                "number" : 70,
                "name" : "AVANTE",
                "legendComposition" : [ 
                    "PMN", 
                    "AVANTE"
                ],
                "initials" : "AVANTE"
            },
            "candidateNumber" : 7015,
            "situation" : "APTO",
            "age" : 31,
            "nameExibition" : "HIPLITO DOMARCO"
        }
    ]
}
```

O atributo *electionInformation* é um array que pode armazenar várias eleições onde o candidato participou, e tem vários atributos que podem ser utilizados para fazer qualquer tipo de pesquisa. Por exemplo, se quisermos exibir todos os candidatos que fazem parte de um determinado Partido:

```javascript
db.candidates.find({
    "electionInformation.politicalParty.initials":"AVANTE"
})
```

Executando essa consulta teríamos o seguinte plano de execução:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jas6qo0hfxf3xgrm3f66.png)

Na imagem acima temos algumas informações importantes sobre nossa query. A primeira delas é que como não temos um índice o jeito foi fazer um **COLLSCAN**, nesse caso o MongoDB teve que examinar cada um dos 7.651 documentos da coleção para retornar apenas 398 resultados e essa operação levou 8ms. E o [MongoDB Compass](https://www.mongodb.com/products/compass) nos sinalizou que não existe um índice para suportar essa query.

Agora vamos criar um índice do tipo Wildcard e ver como nosso plano de execução se comporta:

```javascript
db.candidates.createIndex(
    { "electionInformation.$**" : 1 } 
)
```

Executando a mesma query, temos o seguinte plano de execução:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/kf1fo4mk278xxfvqm7gl.png)

Bem melhor, né?! Agora o MongoDB conseguiu utilizar o índice criado e executou a query em 0ms! Notem que os números de documentos examinados (Documents Examined) e documentos retornados (Documents Returned) são iguais e também condizem com o número de "entradas no índice" (Index Key Examined), isso significa que ele utilizou somente o índice pra satisfazer essa query, por isso ficou bem mais rápido!

"Ah Leandro, mas isso eu conseguiria fazer criando um índice específico para o atributo *electionInformation.politicalParty.initials*. Onde o Wildcard entra nisso?"

Sim, um índice específico resolveria, mas lembra do início do post, podemos não saber quais atributos existem, ou não criar índices para cada um desses atributos, logo, podemos fazer uma query por outro atributo existente:

```javascript
db.candidates.find({
     "electionInformation.role.description":"DEPUTADO FEDERAL"
})
```

O MongoDB utilizará o mesmo índice:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/aiayp4fnfvw30yivv8bw.png)

Viu só? Isso, como eu disse, facilita muito em casos de schema dinâmico e também na manutenção dos índices! Claro que existem considerações e restrições que devem ser observadas, mais informações sobre o Wildcard Index você encontra [aqui](https://docs.mongodb.com/manual/core/index-wildcard/).

Se quiser testar esse novo tipo de índice e não tem o MongoDB 4.2 instalado, utilize o [MongoDB Atlas](https://www.mongodb.com/cloud/atlas), lá você pode criar um Replica Set para testes totalmente free!

Também se quiser ter um overview sobre algumas das principais novidades da versão 4.2, dê uma [olhada aqui](https://dev.to/delbussoweb/mongodb-4-2-o-que-vem-por-ai-4b7i).

É isso, espero que tenham gostado e fiquem à vontade para comentar e compartilhar!

Um abraço e até mais!