> For the complete documentation index, see [llms.txt](https://jorgeguerrabrazil-github.gitbook.io/curso-no-mongoose/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jorgeguerrabrazil-github.gitbook.io/curso-no-mongoose/esquemas/aprenda-a-definir-seu-esquema.md).

# Definindo seu esquema

## Introdução&#x20;

Em Mongoose, tudo começa com um Esquema (*Schema*). Cada esquema mapeia para uma coleção no MongoDB. Adicionalmente, esse esquema defini o formato da coleção e documentos. Quando se trabalha com Mongoose, grande parte dos detalhes do MongoDB são abstraídos, isso fica ainda mais forte se usarmos [NestJS](https://docs.nestjs.com/recipes/mongodb), que vamos falar sobre no curso; contudo, um passo de cada vez😎 .&#x20;

{% hint style="info" %}
Sugestão de leitura, focado no MongoDB: Shannon Bradshaw, Eoin Brazil, Kristina Chodorow. MongoDB: The Definitive Guide: Powerful and Scalable Data Storage 3rd Edição.
{% endhint %}

## Nosso primeiríssimo esquema😎

Dizem que  o primeiro sempre fica: o primeiro beijo💋, o primeiro programa de computador, a primeira língua. Sendo assim, vamos fazer direito. Nosso primeiro esquema abaixo!  😊

Neste esquema, estamos criando um documento que possui vários campos.&#x20;

```javascript
const blogSchema = new Schema({
    title: String, // String is shorthand for {type: String}
    author: String,
    body: String,
    comments: [{ body: String, date: Date }],
    date: { type: Date, default: Date.now },
    hidden: Boolean,
    meta: {
        votes: Number,
        favs: Number
    }
});

```

* Cada linha define um *path,* vamos chamar de atributos em PT. Cada atributo tem seu tipo, ou seja, Mongoose é "tipado", como Java. Caso tente chamar tipos diferentes, aparecerá uma mensagem de erro, e não conseguirá salvar; &#x20;
* Na linha 5, temos um vetor de objetos JSON;
* Note na linha 6 o uso da palavra `default`, isso é uma forma de se colocar um valor caso não seja passado nada; Isso pode ser útil em situações onde ter um valor é importante, mesmo que seja um padrão; &#x20;
* Note na linha 8 um objeto dentro de um atributo, deverá ser acessado como `meta.votes`, como exemplo. Existem algumas desvantagens de se declarar atributos desta forma, ver documentação oficial para mais detalhes!

{% hint style="info" %}
&#x20;Desnecessário repetir, estamos nos baseando na [documentação oficial](https://mongoosejs.com/docs/guide.html)!
{% endhint %}

## Criando seu modelo

Criamos nosso esquema. E agora?🤔 Agora precisamos dizer para o Mongoose salvar nosso esquema!

Usamos o comando `mongoose.model(modelName, schema)`.&#x20;

Onde:&#x20;

* `modelName`é o nome do modelo, será salvo internamente no Mongoose, podendo ser acessado como variável global. O padrão é ser sempre maiúsculo, mas não obrigatório;&#x20;
* `schema`é o esquema que criamos;

```javascript
//Schema.js
const Blog = mongoose.model('Blog', blogSchema);
//Estamos prontos para trabalhar
```

## ID

Lembra no "Ligando os motores", testamos os ID, vamos fazer mais alguns testes, como forma de continuar a discussão. Apesar das discussões serem ricas e importantes, nesta primeira edição deste GitBook, não vamos nos aprofundar além disso, pois queremos deixar espaço para falar do Mongoose e dos testes no NestJS!

Vamos fazer dois testes, somente para efeito de discussão.

```javascript
describe("test 1: Estamos testando se o ID foi adicionado propriamente", () => {
    it("O id deve ser adicionado automaticamente", () => {
        const doc = { title: "String" }
        const esquema = new Blog(doc);

        return esquema.save((err, esquema) => {
            if (err) return console.error(err);
            expect(objectid.isValid(esquema._id)).toBeTruthy();
        })
    })
})

```

```javascript
describe("test 2: Mongoose creates a new _id of type ObjectId to your document.", () => {
    it("O id deve ser adicionado automaticamente", () => {
        const esquema = new Blog();
        expect(esquema._id instanceof mongoose.Types.ObjectId).toBeTruthy();
    })

    it("Testando id depois de salvar", () => {
        const esquema = new Blog();

        return esquema.save((err, esquema) => {
            if (err) return console.error(err);
            expect(esquema._id).toBeTruthy();

        })
    })
})

```

{% hint style="info" %}
A linha 4 testa algo muito importante: que o id é um objeto Mongoose. Isso é importante quando usamos `populate`, ver meu vídeo sobre isso: Usando [o populate em mongoose](https://www.youtube.com/watch?v=IBZSnb2dxFs) .
{% endhint %}

{% hint style="info" %}
Na linha 12, tivemos de modificar comparado com a documentação oficial. Nunca usei `path`, parece que não funciona.&#x20;
{% endhint %}
