Em qualquer negócio, os dados são o seu maior ativo. Ao analisar os dados, você pode tomar decisões sobre as tendências do cliente e a previsão de comportamento. Isto aumenta a lucratividade do negócio e a tomada de decisões efetiva.

Sem um software de banco de dados, uma tarefa simples como encontrar a média de todos os valores em um sistema cheio de registros seria entediante. Felizmente, as bases de dados tornaram a análise de dados mais fácil e rápida com funções e operadores.

Este artigo irá lançar alguma luz sobre os operadores utilizados no software de banco de dados MongoDB.

O que são os operadores MongoDB?

O MongoDB é um software de banco de dados NoSQL que gerencia informações orientadas a documentos.

Uma das principais características do MongoDB é sua velocidade. Para retornar consultas mais rapidamente, a MongoDB pode usar operadores para executar funções específicas.

Os operadores são símbolos especiais que ajudam os compiladores a realizar tarefas matemáticas ou lógicas. O MongoDB oferece vários tipos de operadores para interagir com o banco de dados.

Tipos de operadores MongoDB

Existem nove tipos de operadores, cada um nomeado por sua função. Por exemplo, os operadores lógicos usam operações lógicas. Para executá-las, você precisa usar uma palavra-chave específica e seguir a sintaxe. Entretanto, eles são bastante fáceis de seguir!

Ao final do artigo, você será capaz de aprender o básico de cada operador e suas funções.

Operadores lógicos

Operadores lógicos são frequentemente usados para filtrar dados com base nas condições dadas. Eles também permitem a avaliação de muitas condições, que discutiremos em mais detalhes.

Abaixo estão alguns poucos operadores lógicos que você pode usar:

$and

Uma condição “and” realiza uma operação lógica “e” em uma matriz de duas ou mais expressões. Ela seleciona os documentos onde todas as condições das expressões são satisfeitas.

Esta é a sintaxe padrão para a expressão $and:

{ $and: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
db.inventory.find( { $and: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

$or

Uma condição “or” realiza uma operação lógica “ou” em uma matriz de duas ou mais expressões. Ela seleciona os documentos onde pelo menos uma das expressões é verdadeira.

Esta é a sintaxe padrão para a expressão $or:

{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }.

Por exemplo, se quisermos selecionar documentos onde o preço é $10 ou a quantidade é inferior a 15, podemos inserir a seguinte consulta:

db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

Nós não temos que limitar a expressão a dois critérios – podemos acrescentar mais. Por exemplo, a consulta abaixo seleciona aqueles documentos onde o preço é igual a $10, a quantidade é inferior a 15, ou a etiqueta é estacionária:

db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 }, { tag: "stationary" }] } )

Ao executar estas cláusulas, o MongoDB realiza uma varredura de coleção ou uma varredura de índice. Caso todos os índices suportam as cláusulas, então MongoDB usa índices para verificar uma expressão $or. Caso contrário, ele usa uma verificação de coleção em seu lugar.

Mas se você quiser testar os critérios no mesmo campo, você pode querer usar o operador $in ao invés do operador $or. Por exemplo, se você quiser uma coleção de documentos onde a quantidade seja 10 ou 20, você pode ter que executar a consulta abaixo $in em vez disso:

db.inventory.find ( { quantity: { $in: [20, 50] } } )

Cobriremos mais sobre o operador $in mais tarde.

$nor

Este operador realiza uma operação lógica “nor” em uma matriz usando uma ou mais expressões. Em seguida, ele seleciona os documentos que falham nas expressões de consulta. Em termos mais simples, ele faz o oposto da condição $or.

Esta é a sintaxe geral:

{ $nor: [ { <expression1> }, { <expression2> }, ...  { <expressionN> } ] }

Vamos considerar a seguinte pergunta:

db.inventory.find( { $nor: [ { price: 3.99 }, { sale: true } ]  } )

Esta consulta seleciona os documentos que contêm:

  • um valor de campo de preço não igual a $3,99, e um valor de venda não igual a verdadeiro; ou
  • um valor de campo de preço não igual a $3,99, e um campo de venda vazio ou ausente; ou
  • sem campo de preço, e um campo de venda não igual a verdadeiro; ou
  • nem campo de preços, nem campo de vendas povoado ou presente.

$not

Este operador realiza uma operação lógica “not” em uma matriz para a expressão especificada. Ele então seleciona os documentos que não combinam com as expressões de consulta. Isto inclui os documentos que não contêm o campo.

Esta é a sintaxe geral:

{ field: { $not: { <operator-expression> } } }

Por exemplo, pegue a seguinte pergunta:

db.inventory.find( { price: { $not: { $lt: 3.99 } } } )

Esta consulta selecionaria os documentos que contêm:

  • um campo de preço cujo valor seja maior ou igual a $3,99; e
  • um campo de preços é despovoado ou não existe.

Operadores de comparação

Os operadores de comparação podem ser usados para comparar valores em um ou mais documentos.

Abaixo está uma amostra de código de uma simples coleta de estoque para uma loja de supermercado:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] },
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] },
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] },
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] },
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] },
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Vamos usar este exemplo enquanto detalhamos cada operador de comparação a seguir.

Igual a ($eq)

Este operador corresponde aos valores que são iguais ao valor dado:

{ <field>: { $eq: <value> } }

Por exemplo, se quisermos recuperar um documento específico da coleção de inventário com o valor exato da quantidade “20”, inserimos o seguinte comando:

db.inventory.find( { qty: { $eq: 20 } } )

A consulta retornaria o seguinte:

{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }, 
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Maior do que ($gt)

Este operador corresponde se os valores forem maiores que o valor dado:

{ field: { $gt: value } }

Neste exemplo, nós recuperamos os documentos onde a quantidade é maior que 15:

db.inventory.find({"qty": { $gt: 15}})

A consulta retornaria o seguinte:

{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Menor do que ($lt)

Este operador corresponde se os valores forem menores que o valor fornecido:

{ field: { $lt: value } }

Vamos encontrar os documentos com uma quantidade inferior a 25:

db.inventory.find({"qty": { $lt: 25}})

A consulta retornaria o seguinte:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Maior ou igual a ($gte)

Este operador combina quando os valores são maiores ou iguais ao valor dado:

{ field: { $gte: value } }

Neste exemplo, nós recuperamos os documentos onde a quantidade é maior ou igual a 25:

db.inventory.find({"qty": { $gte: 25}})

Esta consulta retornaria o seguinte:

{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }

Menor ou igual a ($lte)

Este operador só corresponde se os valores forem menores ou iguais ao valor dado:

{ field: { $lte: value } }

Vamos encontrar os documentos com uma quantidade menor ou igual a 25.

db.inventory.find({"qty": { $lte: 25}})

Podemos esperar que esta consulta retorne o seguinte:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Em ($in)

Este operador retorna os documentos que correspondem aos valores especificados:

{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }

O valor de um campo é igual a qualquer valor na matriz especificada. Para recuperar os documentos com os valores “30” e “15” na coleção de inventário, por exemplo, você faria isso:

db.inventory.find({ "qty": { $in: [30, 15]}})

A saída seria:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }

Não em ($nin)

Este operador devolve os documentos que não correspondem aos valores dados. Aqui está a sintaxe básica do operador $nin:

{ field: { $nin: [ <value1>, <value2> ... <valueN> ]

$nin seleciona os documentos onde:

  • o valor do campo não está na matriz especificada; ou
  • o campo não existe.

Caso o campo contém matrizes, ele irá escolher matrizes onde nenhum elemento especificado na seção de valores está presente. Por exemplo, nós queremos selecionar aqueles documentos onde a quantidade não é igual a 20 ou 15.

Além disso, ele também combina com documentos que não têm um campo de quantidade:

db.inventory.find({ "qty": { $nin: [ 20, 15 ]}})

A saída seria:

{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Não igual ($ne)

O operador $ne retorna os documentos onde o valor especificado não é igual:

{ $ne: value } }

Por exemplo, digamos que queremos selecionar todos os documentos onde a quantidade não é igual a 20:

db.inventory.find( { qty: { $ne: 20 } } )

A saída seria:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Da saída acima, a consulta selecionará documentos que não possuem um campo de quantidade.

Operadores de elementos

Os operadores de consulta de elementos podem identificar os documentos usando os campos do documento. Os operadores de elementos consistem em $exist e $type.

$exists

Este operador combina documentos com um campo específico. Este operador tem um valor booleano que pode ser true ou false.

Se especificado para ser true, ele corresponde aos documentos que contêm aquele campo, incluindo documentos onde o valor do campo é nulo. Se <boolean> é false, então a consulta retorna apenas os documentos que não contêm o campo.

Aqui está a sintaxe padrão:

{ field: { $exists: <boolean> } })

Vamos dar um exemplo onde temos uma coleta de dados para uma matriz chamada “bagofmarbles”, onde cada bolsa contém mármores de diferentes cores:

{ red: 5, green: 5, blue: null }
{ red: 3, green: null, blue: 8 }
{ red: null, green: 3, blue: 9 }
{ red: 1, green: 2, blue: 3 }
{ red: 2, blue: 5 }
{ red: 3, green: 2 }
{ red: 4 }
{ green: 2, blue: 4 }
{ green: 2 }
{ blue: 6 }

Digamos que queremos uma consulta que devolva apenas aqueles sacos onde existem os mármores vermelhos. Isto significa que teríamos que inserir o valor booleano como true. Vamos dar uma olhada:

db.bagofmarbles.find( { red: { $exists: true } } )

Os resultados consistiriam daqueles documentos que contêm o campo “vermelho”, mesmo que o valor fosse null. Entretanto, não consistiria dos documentos onde o campo “vermelho” não existia:

{ red: 5, green: 5, blue: null }
{ red: 3, green: null, blue: 8 }
{ red: null, green: 3, blue: 9 }
{ red: 1, green: 2, blue: 3 }
{ red: 2, blue: 5 }
{ red: 3, green: 2 }
{ red: 4 }

Se quiséssemos apenas as bolsas onde os mármores vermelhos nem sequer existem como um campo, podemos entrar na consulta abaixo:

db.bagofmarbles.find( { red: { $exists: false} )

Os resultados consistiriam naqueles documentos que não contêm o campo “vermelho”:

{ green: 2, blue: 4 }
{ green: 2 }
{ blue: 6 }

$type

Este operador combina documentos conforme o tipo de campo especificado. Isto é útil quando você tem dados altamente não estruturados, ou quando os tipos de dados não são previsíveis. Estes tipos de campo são especificados tipos de BSON e podem ser definidos pelo número do tipo ou aliás.

Esta é a sintaxe geral para $type:

{ field: { $type: <BSON type> } }

Digamos que temos uma lista de endereços contendo os documentos abaixo:

db={
  addressBook: [
    {
      "_id": 1,
      address: "2100 Jupiter Spot",
      zipCode: "9036325"
    },
    {
      "_id": 2,
      address: "25 Moon Place",
      zipCode: 26237
    },
    {
      "_id": 3,
      address: "2324 Neptune Ring",
      zipCode: NumberLong(77622222)
    },
    {
      "_id": 4,
      address: "33 Saturns Moon",
      zipCode: NumberInt(117)
    },
    {
      "_id": 5,
      address: "1044 Venus Lane",
      zipCode: [
        "99883637232",
        "73488976234"
      ]
    }
  ]
}

Ao observar os documentos acima, o código postal tem diferentes tipos de dados. Isto inclui valores longos, duplos, inteiros e string.

Se queremos apenas aqueles documentos com um tipo de dado especificado como o código postal – vamos tomar a string para este exemplo – teríamos que inserir a seguinte consulta no compilador:

db.addressBook.find({
  "zipCode": {
    $type: "string"
  }
})

Isto retornaria os seguintes documentos:

[
  {
    "_id": 1,
    "address": "2100 Jupiter Spot",
    "zipCode": "9036325"
  },
  {
    "_id": 5,
    "address": "1044 Venus Lane",
    "zipCode": [
      "99883637232",
      "73488976234"
    ]
  }
]

Além disso, há um tipo “número”, que inclui todos os valores longos, inteiros ou duplos como um array contendo um elemento dos tipos especificados:

db.addressBook.find( { "zipCode" : { $type : "number" } } )

Saída:

[
{
      "_id": 2,
      address: "25 Moon Place",
      zipCode: 26237
    },
    {
      "_id": 3,
      address: "2324 Neptune Ring",
      zipCode: NumberLong(77622222)
    },
    {
      "_id": 4,
      address: "33 Saturns Moon",
      zipCode: NumberInt(117)
    }
]

Caso os documentos tiverem um tipo de campo array, o operador $type retorna os documentos nos quais pelo menos um elemento array corresponde ao tipo passado para o operador.

Operadores de Array

MongoDB também consiste em operadores de matriz, para consultar documentos contendo matrizes.

Existem três operadores primários: $all, $elemMatch e $size. Discutiremos cada uma delas em detalhes abaixo.

$all

O operador $all escolhe os documentos nos quais o valor de um campo é um array contendo os elementos especificados:

{ : { $all: [ <value1> , <value2> ... ] } }

Por exemplo, digamos que temos uma coleção de documentos para uma loja de roupas, com o seguinte em inventário.

{
   _id: ObjectId("5234cc89687ea597eabee675"),
   code: "shirt",
   tags: [ "sale", "shirt", "button", "y2k", "casual" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 45, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
},

{
   _id: ObjectId("5234cc8a687ea597eabee676"),
   code: "pant",
   tags: [ "y2k", "trendy", "shine" ],
   qty: [
          { size: "6", num: 100, color: "green" },
          { size: "6", num: 50, color: "blue" },
          { size: "8", num: 100, color: "brown" }
        ]
},

{
   _id: ObjectId("5234ccb7687ea597eabee677"),
   code: "pant2",
   tags: [ "trendy", "shine" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 100, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
},

{
   _id: ObjectId("52350353b2eff1353b349de9"),
   code: "shirt2",
   tags: [ "y2k", "trendy" ],
   qty: [
          { size: "M", num: 100, color: "green" }
        ]
}

Queremos recuperar quaisquer documentos (neste caso, as roupas) do inventário, que estão ligados às tags “trendy” e “y2k”. A consulta abaixo usa o operador $all onde o valor do campo das etiquetas é um array cujos elementos incluem “y2k” e “trendy”:

db.inventory.find( { tags: { $all: [ "y2k", "trendy" ] } } )

A consulta acima retorna o seguinte:

{
   _id: ObjectId("5234cc8a687ea597eabee676"),
   code: "pant",
   tags: [ "y2k", "trendy", "shine" ],
   qty: [
          { size: "6", num: 100, color: "green" },
          { size: "6", num: 50, color: "blue" },
          { size: "8", num: 100, color: "brown" }
        ]
}

{
   _id: ObjectId("52350353b2eff1353b349de9"),
   code: "shirt2",
   tags: [ "y2k", "trendy" ],
   qty: [
          { size: "M", num: 100, color: "green" }
        ]
}

A partir do exemplo acima, nós também descobrimos que o operador $all simplesmente desempenha a mesma função que a operação $and.

Alternativamente, nós poderíamos usar a consulta abaixo que daria uma saída como acima:

db.inventory.find({
  $and: [
    {
      tags: "y2k"
    },
    {
      tags: "trendy"
    }
  ]
})

$elemMatch

O operador $elemMatch combina documentos que contêm um campo de matriz com pelo menos um elemento que corresponde a todos os critérios de consulta especificados:

{ : { $elemMatch: { <query1>, <query2>, ... } } }

Embora possamos utilizar operadores de comparação como $lte e $gte, se especificarmos apenas uma única condição de consulta dentro de $elemMatch, e não estivermos utilizando o $not ou os operadores de $ne, a utilização do $elemMatch pode ser omitida, pois ele estaria essencialmente desempenhando a mesma função.

Há mais algumas coisas para se ter em mente ao usar este operador, principalmente:

  • Você não pode especificar uma expressão $where em uma operação $elemMatch.
  • Você não pode especificar uma expressão de consulta $text em uma operação $elemMatch.

Por exemplo, nós temos os seguintes documentos na coleção de resultados dos alunos:

{ _id: 1, results: [ 92, 89, 98 ] }
{ _id: 2, results: [ 85, 99, 99 ] }

A consulta a seguir corresponde apenas àqueles documentos onde a matriz de resultados contém pelo menos um elemento que é maior ou igual a 90 e é menor que 95:

db.studentresults.find(  { results: { $elemMatch: { $gte: 90, $lt: 95 } } })

Nossa consulta retorna o seguinte documento, já que o elemento 92 é maior ou igual a 90 e é inferior a 95:

{ "_id" : 1, "results" :[ 92, 89, 98 ] }

$size

O operador $size retorna aqueles documentos onde o tamanho da matriz corresponde ao número de elementos especificados no argumento:

{ field: { $size: value } }

Aqui está um exemplo:

db.collection.find( { field: { $size: 2 } });

Isto devolveria todos os documentos da coleção especificada onde o campo é um array com 2 elementos: { field: [ orange, apple] } e { field: [ blue, red] }, mas não { field: blue} ou { field: [ raspberry, lemon, grapefruit ] }.

Entretanto, embora possamos inserir o valor específico como o tamanho, não podemos especificar intervalos de valores como o tamanho.

Operadores geoespaciais

O MongoDB permite que você armazene dados geoespaciais na forma de tipos GeoJSON. GeoJSON é um formato de padrão aberto baseado na notação de objetos JavaScript que pode representar características geográficas e suportar atributos não-espaciais. Há dois tipos de operadores geoespaciais que vamos falar neste artigo: especificadores de geometria e seletores de consulta.

$geometry

Este operador menciona a geometria do GeoJSON para uso com os seguintes operadores de consulta geoespacial: $geoIntersects, $geoWithin,$nearSphere, e $near. $geometry alavanca EPSG:4326 como o sistema de referência de coordenadas padrão (CRS).

Para mencionar os objetos GeoJSON com o CRS padrão, você pode aproveitar o seguinte trecho para $geometry:

$geometry: {
   type: "<GeoJSON object type>",
   coordinates: [ <coordinates> ]
}

Para mencionar um polígono GeoJSON de anel único com um CRS MongoDB sob medida, você pode usar o seguinte trecho (você só pode usar isso para $geoWithin e $geoIntersects):

$geometry: {
   type: "Polygon",
   coordinates: [ <coordinates> ],
   crs: {
      type: "name",
      properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
   }
}

$polygon

O operador $polygon pode ser usado para especificar um polígono para uma consulta geoespacial $geoWithin em pares de coordenadas legados. Esta consulta irá então retornar pares que se enquadram nos limites do polígono. Entretanto, $polygon não fará consultas para nenhum objeto GeoJSON. Para definir um polígono, você precisa especificar uma matriz de pontos de coordenadas como a seguir:

{
   : {
      $geoWithin: {
         $polygon: [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
      }
   }
}

Aqui, o último ponto está implicitamente ligado ao primeiro. Você pode mencionar quantos pontos ou lados você quiser.

Por exemplo, a seguinte consulta retornará todos os documentos que têm coordenadas que existem no polígono definido por [0,0], [1,5], e [3,3]:

db.places.find(
  {
     loc: {
       $geoWithin: { $polygon: [ [ 0 , 0 ], [ 1 , 5 ], [ 3 , 3 ] ] }
     }
  }
)

$geoWithin

Este operador pode ser usado para escolher documentos com dados geoespaciais que estão completamente contidos em um formato específico. A forma especificada pode ser um multipolígono GeoJSON, um polígono GeoJSON (multianelar ou anelar único), ou uma forma que pode ser definida por pares de coordenadas legados.

O operador $geoWithin irá aproveitar o operador $geometry para mencionar o objeto GeoJSON.

Para mencionar os multipolígonos ou polígonos GeoJSON através do Sistema de Referência de Coordenadas (CRS) padrão, você pode utilizar a sintaxe mencionada abaixo:

{
   : {
      $geoWithin: {
         $geometry: {
            type: <"Polygon" or "MultiPolygon"> ,
            coordinates: [ <coordinates> ]
         }
      }
   }
}

Para $geoWithin consultas que mencionam as geometrias do GeoJSON com áreas maiores que um único hemisfério, o uso do CRS padrão levaria a consultas para as geometrias complementares.

Para mencionar um polígono GeoJSON de anel único com um CRS MongoDB personalizado, você pode alavancar o protótipo mencionado abaixo na expressão $geometry:

{
   : {
      $geoWithin: {
         $geometry: {
           type: "Polygon" ,
           coordinates: [ <coordinates> ],
           crs: {
              type: "name",
              properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
           }
         }
      }
   }
}

O exemplo a seguir escolhe todos os dados de localização que existem completamente dentro de um polígono GeoJSON, sendo a área do polígono menor do que a área de um único hemisfério:

db.places.find(
   {
     loc: {
       $geoWithin: {
          $geometry: {
             type : "Polygon" ,
             coordinates: [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ]
          }
       }
     }
   }
)

$box

Você pode usar $box para especificar um retângulo para uma consulta geoespacial $geoWithin para fornecer documentos que estão nos limites do retângulo, de acordo com seus dados de localização baseados em pontos. Quando você usar $geoWithin com o $box, você obterá documentos baseados nas coordenadas da consulta. Neste cenário, $geoWithin não fará consultas para nenhuma forma de GeoJSON.

Para alavancar o operador $box, você precisa mencionar os cantos superior direito e inferior esquerdo do retângulo em um objeto de matriz:

{ <location field> : { $geoWithin: { $box: [ [ <bottom left coordinates> ],
 [ <upper right coordinates> ] ] } } }

A consulta mencionada acima calculará a distância utilizando a geometria plana (planar). A consulta a seguir retornará todos os documentos que estão dentro da caixa com pontos em: [0,0], [0,30], [30,0], [30,30]:

db.places.find ( { 
 loc: { $geoWithin: { $box: [ [ 0,0 ], [ 30,30 ] ] } }
} )

$nearSphere

Você pode usar $nearSphere para mencionar um ponto para o qual uma consulta geoespacial retorna os documentos do mais próximo para o mais distante.

MongoDB usa geometria esférica para calcular as distâncias para $nearSphere. Ele precisará de um índice geoespacial como a seguir:

  1. índice 2d para dados de localização descritos como pares de coordenadas legados. Para aproveitar um índice 2d em pontos GeoJSON, você precisa gerar o índice no campo de coordenadas do objeto GeoJSON.
  2. índice 2dsphere para os dados de localização descritos como pontos GeoJSON.

Para mencionar um ponto GeoJSON, você pode alavancar a seguinte sintaxe:

{
  $nearSphere: {
     $geometry: {
        type : "Point",
        coordinates : [ <longitude>, <latitude> ]
     },
     $minDistance: <distance in meters>,
     $maxDistance: <distance in meters> 
  }
}

Aqui, $minDistance e $maxDistance são opcionais. $minDistance pode limitar os resultados aos documentos que estejam pelo menos à distância especificada do centro. Você pode usar $maxDistance para qualquer índice.

Agora, considere uma coleção de “lugares” que consiste em documentos com um campo de localização com um índice de 2dsphere. O exemplo a seguir retornaria os pontos cuja localização é de pelo menos 2.000 metros e no máximo 6.000 metros do ponto que você escolher, ordenados do mais próximo ao mais distante:

db.places.find(
   {
     location: {
        $nearSphere: {
           $geometry: {
              type : "Point",
              coordinates : [ -43.9532, 50.32 ]
           },
           $minDistance: 2000,
           $maxDistance: 6000
        }
     }
   }
)

$geoIntersects

O operador $geoIntersects permite que você selecione documentos cujos dados geoespaciais se cruzam com um objeto GeoJSON particular (isto é, onde a convergência do objeto especificado e os dados não estão vazios). Ele alavanca o operador $geometry para especificar o objeto GeoJSON.

Para mencionar GeoJSON multipolígonos ou polígonos através do sistema de referência de coordenadas padrão (CRS), você pode usar a seguinte sintaxe:

{ <location field>: {
     $geoIntersects: {
        $geometry: {
           type: "<GeoJSON object type>" ,
           coordinates: [ <coordinates> ]
        }
     }
  }
}

A seguinte instância usará $geoIntersects para escolher todos os dados de localização que se cruzam com o polígono descrito pela matriz de coordenadas:

db.places.find(
   {
     loc: {
       $geoIntersects: {
          $geometry: {
             type: "Polygon" ,
             coordinates: [
               [ [ 0, 0 ], [ 2, 6 ], [ 4, 1 ], [ 0, 0 ] ]
             ]
          }
       }
     }
   }
)

$center

O operador $center menciona um círculo para uma consulta $geoWithin que retorna os pares de coordenadas legados que estão nos limites do círculo.

$center não devolve objetos GeoJSON. Para alavancar o operador $center, você precisa especificar um array que contenha:

  1. O raio do círculo, conforme medido nas unidades usadas pelo sistema de coordenadas.
  2. As coordenadas de grade do ponto central do círculo.
{
  <location field> : {
      $geoWithin: { $center: [ [ <x> , <y> ] , <radius> ] }
   }
}

O exemplo mencionado abaixo irá retornar todos os documentos que possuem coordenadas que podem ser encontradas dentro do círculo centrado em [2,3] e com um raio de 40:

db.places.find(
   { loc: { $geoWithin: { $center: [ [2, 3], 40 ] } } }
)

Operadores de projeção

Você pode usar operadores de projeção para mencionar os campos devolvidos por uma operação. Os operadores de projeção MongoDB permitem que a função find() seja usada com argumentos de filtragem de dados. Isto ajuda os usuários a extrair apenas os campos de dados requeridos de um documento. Assim, ele permite que você projete dados transparentes e concisos sem afetar o desempenho geral do banco de dados.

$elemMatch (projeção)

O operador $elemMatch é responsável por limitar o conteúdo de um campo a partir dos resultados da consulta para conter apenas o primeiro elemento que corresponda à condição $elemMatch.

Aqui estão algumas coisas que você precisa ter em mente antes de usar $elemMatch:

  • De MongoDB 4.4, independentemente da ordenação dos campos no documento, a projeção $elemMatch de um campo existente retorna o campo após a inclusão de outros campos existentes.
  • Ambos os operadores $elemMatch e $ retratam o primeiro elemento correspondente a partir de um array baseado em uma condição especificada. O operador $ projetaria o primeiro elemento de matriz correspondente de cada documento em uma coleção baseada em alguma condição da declaração de consulta, enquanto o operador de projeção $elemMatch pega um argumento de condição explícito. Isto permite que você projete baseado em uma condição não presente na consulta, ou se você precisar projetar baseado em vários campos nos documentos embutidos da matriz.

Você também deve estar ciente das seguintes restrições antes de usar o operador $elemMatch em seus dados:

  • Você não pode mencionar uma expressão de consulta $text dentro de um operador $elemMatch.
  • db.collection.find() as operações em views não suportam o operador de projeção $elemMatch.

O seguinte exemplo no $elemMatch operador de projeção assume uma coleção schools com os seguintes documentos:

{
 _id: 1,
 zipcode: "63108",
 students: [
              { name: "mark", school: 102, age: 9 },
              { name: "geoff", school: 101, age: 13 },
              { name: "frank", school: 104, age: 12 }
           ]
}
{
 _id: 2,
 zipcode: "63110",
 students: [
              { name: "harry", school: 103, age: 14 },
              { name: "george", school: 103, age: 7 },
           ]
}
{
 _id: 3,
 zipcode: "63108",
 students: [
              { name: "harry", school: 103, age: 14 },
              { name: "george", school: 103, age: 7 },
           ]
}
{
 _id: 4,
 zipcode: "63110",
 students: [
              { name: "jim", school: 103, age: 9 },
              { name: "michael", school: 103, age: 12 },
           ]
}

Neste caso, a operação find() consulta todos os documentos onde o valor do campo CEP é 63110. A projeção $elemMatch retornaria apenas o primeiro elemento correspondente do array students onde o campo school tem um valor de 103:

db.schools.find( { zipcode: "63110" },
                 { students: { $elemMatch: { school: 103 } } } )

Este é o resultado que o resultado pareceria:

{ "_id" : 2, "students" : [ { "name" : "harry", "school" : 103, "age" : 14 } ] }
{ "_id" : 4, "students" : [ { "name" : "jim", "school" : 103, "age" : 9 } ] }

$slice (projeção)

O operador de projeção $slice pode ser usado para especificar o número de elementos em um array para retornar no resultado da consulta:

db.collection.find(
   <query> ,
   { <arrayField> : { $slice: <number> } }
);

Ela também pode ser expressa desta forma:

db.collection.find(
  <query> ,
   { <arrayField> : { $slice: [ <number> , <number> ] } }
);

Para demonstrar o mesmo, você pode criar uma coleção de exemplos de tweets com os seguintes documentos:

db.posts.insertMany([
   {
     _id: 1,
     title: "Nuts are not blueberries.",
     comments: [ { comment: "0. true" }, { comment: "1. blueberries aren't nuts."} ]
   },
   {
     _id: 2,
     title: "Coffee please.",
     comments: [ { comment: "0. Indubitably" }, { comment: "1. Cuppa tea please" }, { comment: "2. frappucino" }, { comment: "3. Mocha latte" }, { comment: "4. whatever" } ]
   }
])

A operação seguinte usaria o operador de projeção $slice na matriz de tweets para retornar a matriz com seus dois primeiros elementos. Caso um array contém menos de dois elementos, todos os elementos do array são devolvidos:

db.posts.find( {}, { comments: { $slice: 2 } } )

Essa operação devolveria os seguintes documentos:

{
   "_id" : 1,
   "title" : "Nuts are not blueberries.",
   "comments" : [ { "comment" : "0. true" }, { "comment" : "1. blueberries aren't nuts." } ]
}
{
   "_id" : 2,
   "title" : "Coffee please.",
   "comments" : [ { "comment" : "0. Indubitably" }, { "comment" : "1. Cuppa tea please" } ]
}

$ (projeção)

O operador posicional $ limita o conteúdo de uma matriz para retornar o primeiro elemento que corresponda à condição de consulta dessa matriz. Você pode usar $ no documento de projeção do método find() ou o método findOne() quando você precisar apenas de um elemento de array em particular nos documentos escolhidos.

É assim que se parece a sintaxe do operador $:

db.collection.find( { <array>: <condition> ... },
                    { "<array>.$": 1 } )
db.collection.find( { <array.field>: <condition> ...},
                    { "<array>.$": 1 } )

Neste exemplo, a coleção students é composta pelos seguintes documentos:

{ "_id" : 1, "semester" : 2, "grades" : [ 75, 67, 93 ] }
{ "_id" : 2, "semester" : 2, "grades" : [ 60, 68, 72 ] }
{ "_id" : 3, "semester" : 2, "grades" : [ 95, 82, 67 ] }
{ "_id" : 4, "semester" : 3, "grades" : [ 89, 95, 70 ] }
{ "_id" : 5, "semester" : 3, "grades" : [ 68, 98, 82 ] }
{ "_id" : 6, "semester" : 3, "grades" : [ 65, 70, 76 ] }

Na consulta seguinte, a projeção { "grades.$": 1 } retorna apenas o primeiro elemento maior ou igual a 89 para o campo grades:

db.students.find( { semester: 2, grades: { $gte: 89 } },
                  { "grades.$": 1 } )

Esta operação retorna os seguintes documentos:

{"_id": 1, "grades": [93] }

Operadores de Avaliação

Você pode aproveitar os operadores de avaliação da MongoDB para medir a estrutura geral dos dados ou o campo individual dentro de um documento.

Vamos olhar para alguns operadores comuns de avaliação do MongoDB.

$mod

Você pode usar este operador para combinar documentos onde o valor de um campo especificado é igual ao valor restante após ser dividido por um valor especificado:

{ field: { $mod: [ divisor, remainder ] } }

Digamos que você tenha uma tabela de carros pertencentes a diferentes marcas que você possui em seu showroom. A seguinte consulta lhe daria todas as marcas de carros cujos números de estoque estão em múltiplos de 250.

db.cars.find ( { qty: { $mod: [ 250,0 ] } } )

$jsonSchema

O $jsonSchema permite que você combine os documentos que combinam com o esquema JSON especificado. A implementação do esquema JSON pelo MongoDB inclui a adição da palavra-chave bsonType, que permite a você usar todos os tipos de BSON no operador $jsonSchema.

bsonType pode aceitar os mesmos pseudônimos de cadeia que você usaria para o operador type. Isto é o que a sintaxe do $jsonSchema pareceria:

{ $jsonSchema: <JSON Schema object> }

Aqui, o objeto do esquema JSON é formatado com base no rascunho 4 do padrão de esquema JSON:

{ <keyword1>: <value1>, ... }

Aqui está um exemplo para demonstrar como $jsonSchema funciona:

{ $jsonSchema: {
     required: [ "name", "major", "gpa", "address" ],
     properties: {
        name: {
           bsonType: "string",
           description: "must be a string and is required"
        },
        address: {
           bsonType: "object",
           required: [ "zipcode" ],
           properties: {
               "street": { bsonType: "string" },
               "zipcode": { bsonType: "string" }
           }
        }
     }
  }
}

Você também pode usar $jsonSchema em um validador de documentos para aplicar o esquema especificado nas operações de atualização e inserção:

db.createCollection(<collection> , { validator: { $jsonSchema: <schema> } } )
db.runCommand( { collMod: <collection>, validator:{ $jsonSchema: <schema> } } )

Tenha em mente que há várias coisas que não são suportadas pelo operador $jsonSchema:

  1. O tipo inteiro. Você precisa aproveitar o tipo BSON longo ou int com a palavra-chave bsonType.
  2. Palavras-chave desconhecidas.
  3. Ligação de propriedades e a hipermídia do esquema JSON, com o uso de referências JSON e ponteiros JSON.

$text

O operador $text buscaria um texto dentro do conteúdo do campo especificado, indexado com um índice de texto:

{  
  $text:  
    {  
      $search: <string>,  
      $language: <string>,  
      $caseSensitive: <boolean>,  
      $diacriticSensitive: <boolean>   
    }  
}

Neste caso, o seguinte trecho de código irá peneirar na tabela para filtrar qualquer carro que tenha o texto “Porsche” dentro deles:

db.cars.find( { $text: { $search: "Porsche" } } )

$regex

O operador $regex oferece habilidades de expressão regular para combinar strings em consultas. MongoDB alavanca expressões regulares compatíveis com o Perl:

{<field> : /pattern/ <options>}

O exemplo a seguir ajudaria a filtrar todos os carros com a string “$78900” presente neles:

db.cars.find( { price: { $regex: /$78900/ } } )

$expr

O operador $expr permite que você utilize expressões de agregação na linguagem da consulta:

{ $expr: { <expression> } }

Você também pode usar $expr para construir expressões de consulta que comparam campos do mesmo documento em uma etapa $match. Se o estágio $match for parte de um estágio $lookup, $expr pode comparar campos com a ajuda de variáveis let.

$where

Você pode aproveitar o operador $where para passar uma string contendo uma função JavaScript completa ou uma expressão JavaScript para o sistema de consulta. O operador $where fornece maior flexibilidade, mas precisa do banco de dados para processar a função ou expressão JavaScript para cada documento da coleção. Você pode referenciar este documento na função ou expressão JavaScript usando o obj ou this.

Aqui está um exemplo da sintaxe:

{ $where: <string|JavaScript Code> }

Há algumas considerações importantes a serem consideradas antes de mergulharmos em um exemplo enquanto usamos o operador $where:

  • Você só deve usar o operador de consulta $where para documentos de alto nível. O operador de consulta $where não funcionará em um documento aninhado, como em uma consulta $elemMatch.
  • Geralmente, você deve usar $where somente quando você não puder expressar sua consulta através de outro operador. Caso você tiver que usar $where, certifique-se de incluir pelo menos um outro operador de consulta padrão para filtrar o conjunto de resultados. O uso do $where de forma independente requer uma varredura de coleta para uma execução adequada.

Aqui está um exemplo para ilustrar isto:

db.cars.find( { $where: function() {  
   return (hex_md5(this.name)== "9a43e617b50cd379dca1bc6e2a8")  
} } );

Operadores Bitwise

Os operadores Bitwise retornam dados com base nas condições de posição dos bits. Simplificando, eles são usados para combinar valores numéricos ou binários nos quais qualquer bit de um conjunto de posições de bit tem um valor de 1, ou 0.

$bitsAllSet

Este operador combinará todos os documentos onde todas as posições de bit fornecidas pela consulta estão definidas (i.e. 1) no campo:

{ <field> : { $bitsAllSet: <numeric bitmask> } }
{ <field> : { $bitsAllSet: < BinData bitmask> } }
{ <field> : { $bitsAllSet: [ <position1> , <position2> , ... ] } }

O valor do campo deve ser ou uma instância BinData, ou numérico para $bitsAllSet para corresponder ao documento atual.

No exemplo a seguir, nós estamos alavancando uma coleção com os seguintes documentos:

db.collection.save({ _id: 1, a: 54, binaryValueofA: "00110110" })
db.collection.save({ _id: 2, a: 20, binaryValueofA: "00010100" })
db.collection.save({ _id: 3, a: 20.0, binaryValueofA: "00010100" })
db.collection.save({ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" })

A consulta mencionada abaixo usará o operador $bitsAllSet para testar se o campo a tem bits definidos na posição 1 e posição 5, onde o bit menos significativo estaria na posição 0:

db.collection.find( { a: { $bitsAllSet: [ 1, 5 ] } })

Esta consulta corresponderia aos seguintes documentos:

{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" }
{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" }

$bitsAllClear

O operador $bitsAllClear irá comparar documentos nos quais todas as posições de bits fornecidas pela consulta são claras ou 0:

{ <field> : { $bitsAllClear: <numeric bitmask> } }
{ <field> : { $bitsAllClear: < BinData bitmask> } }
{ <field> : { $bitsAllClear: [ <position1> , <position2> , ... ] } }

Vamos usar o exemplo usado para $bitsAllSet aqui para demonstrar o uso do $bitsAllClear. A seguinte consulta usaria este operador para verificar se o campo a tem os bits claros nas posições 1 e 5:

db.collection.find( { a: { $bitsAllClear: [ 1, 5 ] } } )

Esta consulta corresponderia aos seguintes documentos:

{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" }
{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" }

Operadores Meta

Há vários modificadores de consulta que permitem modificar o comportamento ou a saída de uma consulta no MongoDB. As interfaces do driver podem fornecer métodos de cursor que as embrulham para seu uso.

$hint

MongoDB depreciado $hint desde a v3.2. Mas, este operador ainda pode estar disponível para motoristas do MongoDB como Go, Java, Scala, Ruby, Swift, etc. Ele pode forçar o otimizador de consultas a alavancar um índice específico para preencher a consulta, que pode então ser mencionado ou por documento, ou por nome do índice.

Você também pode usar o operador $hint para testar estratégias de indexação e consultar o desempenho. Por exemplo, pegue a seguinte operação:

db.users.find().hint( { age: 1 } )

Esta operação devolveria todos os documentos da coleção chamada users, alavancando o índice no campo age.

Você também pode mencionar uma dica usando um dos seguintes formulários:

db.users.find()._addSpecial( "$hint", { age : 1 } )
db.users.find( { $query: {}, $hint: { age : 1 } } )

Caso existir um filtro de índice para a forma da consulta, a MongoDB simplesmente ignoraria o $hint.

$comment

O operador $comment permite que você anexe um comentário a uma consulta em qualquer contexto que $query possa aparecer. Como os comentários se propagam ao registro de perfil, adicionar um comentário pode facilitar a interpretação e o rastreamento do seu perfil.

Você pode alavancar $comment em uma das três maneiras:

db.collection.find( { <query> } )._addSpecial( "$comment", <comment> )
db.collection.find( { <query> } ).comment( <comment> )
db.collection.find( { $query: { <query> }, $comment: <comment> } )

Se você quiser anexar comentários a expressões de consulta em outros contextos, como com db.collection.update(), alavanque o operador de consulta $comment ao invés do meta-operador.

$max

Você pode mencionar um valor $max para especificar o limite superior exclusivo para um determinado índice para restringir os resultados de find(). Este operador especificará o limite superior para todas as chaves de uma ordem específica no índice.

Mongosh dá a você o seguinte método max():

db.collection.find( { <query> } ).max( { field1: <max value> , ... fieldN: <max valueN> } )

Você também pode mencionar $max com os dois formulários a seguir:

db.collection.find( { <query> } )._addSpecial( "$max", { field1: <max value1> ,
 ... fieldN: <max valueN> } )
db.collection.find( { $query: { <query> }, $max: { field1: <max value1> ,
 ... fieldN: <max valueN> } } )

Por exemplo, se você quiser especificar o limite superior exclusivo, tenha em mente as seguintes operações em uma coleção chamada coleção que contém um índice { age: 1 }:

db.collection.find( { <query> } ).max( { age: 100 } ).hint( { age: 1 } )

Esta operação limitará a consulta àqueles documentos onde a idade do campo é inferior a 100 anos e força um plano de consulta que irá digitalizar o índice { age: 1 } de minKey para 100.

$explain

Este operador irá lhe dar informações sobre o plano de consulta. Ele retorna um documento que descreve os índices e processos usados para retornar a consulta. Isto pode ser útil quando se tenta otimizar uma consulta.

Você pode mencionar o operador $explain em qualquer uma das seguintes formas:

db.collection.find()._addSpecial( "$explain", 1 )
db.collection.find( { $query: {}, $explain: 1 } )

Melhores práticas para os Operadores MongoDB

Nesta seção, nós vamos dar uma olhada em algumas das melhores práticas enquanto usamos estes operadores MongoDB.

Integração e referenciamento

A incorporação é uma extensão natural da modelagem de dados. Ele permite que você evite inscrições, o que pode reduzir atualizações e consultas.

Você pode incorporar dados com uma relação 1:1 em um único documento. Dito isto, dados com um relacionamento muitos: 1 em que “muitos” objetos aparecem com seus documentos de origem também podem ser bons candidatos.

Armazenar esses tipos de dados no mesmo documento soa como uma escolha prudente. Entretanto, a incorporação proporciona um melhor desempenho para operações de leitura com este tipo de localidade de dados.

Os modelos de dados incorporados também podem ajudar os desenvolvedores a atualizar os dados associados em uma única operação de gravação. Isto funciona porque as gravações de um único documento são transacionais.

Você deve considerar o uso de referências para os seguintes cenários:

  • Quando você atualiza um segmento de documento e ele continua ficando mais longo, enquanto o resto do documento é estático.
  • Quando um documento é acessado, mas contém dados que são raramente usados. Incorporar só aumentaria os requisitos de memória, então o referenciamento faz mais sentido.
  • Quando o tamanho do documento ultrapassa o limite de documentos de 16 MB do MongoDB. Isto pode acontecer quando se modelam muitos: 1 relacionamentos (por exemplo, funcionários: departamento).

Examine os perfis e padrões de consulta

Para a maioria dos desenvolvedores, o primeiro passo para otimizar o desempenho é entender os padrões de consulta reais e esperados. Uma vez que você conheça bem os padrões de consulta do seu aplicativo, você pode fazer seu modelo de dados e escolher os índices apropriados.

Os desenvolvedores do MongoDB têm acesso a várias ferramentas poderosas que lhes permitem melhorar o desempenho. Mas isso não significa que perfis e padrões de consulta podem ser ignorados.

Por exemplo, uma maneira fácil de aumentar o desempenho é analisar seus padrões de consulta e entender onde você pode incorporar dados. Outras formas de reforçar o desempenho do MongoDB após identificar seus principais padrões de consulta incluem:

  • Certificando-se de que você tenha índices em quaisquer campos que você consultar.
  • Armazenando os resultados de subconsultas frequentes em documentos para reduzir a carga de leitura.
  • Dando uma olhada em seus logs para ver as consultas lentas, e então verificar seus índices.

Revisão de indexação de dados e modelagem

Ao fazer seu modelo de dados, você estará decidindo como modelar as relações entre os dados. Escolher quando incorporar um documento versus criar uma referência em documentos separados em coleções diferentes, por exemplo, é um exemplo de consideração específica do aplicativo.

Uma grande vantagem dos documentos do JSON é que eles permitem aos desenvolvedores modelar os dados com base nos requisitos do aplicativo. Os subdocumentos e matrizes de agrupamento ajudam a modelar relações complexas entre os dados, alavancando documentos de texto simples.

Você também pode usar o MongoDB para modelar o seguinte:

  • Dados geoespaciais
  • Estruturas tabulares, planas e colunares
  • Pares simples de valores-chave
  • Dados da série temporal
  • Bordas e nodes de estruturas de dados gráficos conectados e similares

Monitoramento de compartilhamento e replicação

A replicação pode ser fundamental para melhorar o desempenho, uma vez que aumenta a disponibilidade de dados através de escalas horizontais. A replicação pode levar a um melhor desempenho e mais segurança através da redundância.

O monitoramento de desempenho pode ser um incômodo que requer recursos e tempo adicionais para garantir o bom funcionamento. Você pode aproveitar as ferramentas de monitoramento de desempenho disponível no mercado que atendem às suas necessidades específicas.

Por exemplo, o Kinsta APM pode obter informações marcadas no tempo sobre as consultas ao banco de dados MySQL do seu site WordPress, processos PHP, chamadas HTTP externas, e muito mais. Você também pode usar esta ferramenta gratuita para depurar:

  • Chamadas API longas
  • Solicitações de URLs externas longas
  • Consultas lentas de banco de dados para citar algumas.

No MongoDB, a replicação pode ser alcançada por réplicas que permitem aos desenvolvedores copiar dados de um node primário ou servidor através de múltiplos secundários. Isto permite que sua replicação execute algumas consultas nos secundários ao invés dos primários, evitando contenções e levando a um melhor balanceamento de carga.

Os clusters fragmentados em MongoDB são outra forma de melhorar potencialmente o desempenho. Semelhante à replicação, o sharding pode ser usado para distribuir grandes conjuntos de dados em múltiplos servidores.

Ao aproveitar uma chave de fragmento, os desenvolvedores podem copiar fragmentos ou pedaços de dados através de múltiplos servidores. Estes servidores podem trabalhar em conjunto para usar todos os dados.

O Sharding tem sua quota-parte de vantagens, incluindo escalonamento horizontal para escritas/leitura, maior disponibilidade e maior capacidade de armazenamento.

Determinar o uso de memória

MongoDB tem melhor desempenho quando o conjunto de trabalho de um aplicativo (ou seja, dados e índices frequentemente acessados) cabe na memória sem problemas. Enquanto outros fatores são fundamentais para o desempenho, o tamanho da RAM é o mais importante, por exemplo, o dimensionamento.

Quando o conjunto de trabalho de um aplicativo se encaixa na RAM, a atividade de leitura a partir do disco precisa ser baixa. Mas se seu conjunto de trabalho exceder a RAM do servidor ou tamanho da instância, a atividade de leitura começará a disparar.

Caso você vir isso acontecer, você pode conseguir resolver o problema passando para uma instância maior que tenha mais memória.

Coloque campos de valores múltiplos no final

Caso você está indexando alguns campos, e um dos campos que você quer consultar usa um desses operadores “multi-valores”, então você deve colocá-los no final do índice. Você precisa ordenar o índice para que os campos consultados para valores exatos venham primeiro e os operadores “multi-valores” apareçam em último lugar no índice.

Uma exceção a isto seria a classificação contra os campos. Coloque estes entre os campos “multi-valor” e os campos exatos para cortar a quantidade necessária de ordenação na memória.

Resumo

Para MongoDB, velocidade é o nome do jogo. Para retornar consultas rapidamente, o MongoDB alavanca os operadores para executar tarefas matemáticas ou lógicas. Simplificando, entender os operadores do MongoDB é a chave para dominar o MongoDB.

Este artigo destacou alguns dos principais operadores MongoDB que você pode usar em seus dados, como operadores de comparação, operadores lógicos, meta operadores, e operadores de projeção, para citar alguns. Ele também ajuda você a entender como você pode usar os operadores MongoDB e as melhores práticas que permitirão que você obtenha o melhor deles.

Entre todos os operadores, qual(is) você usa com mais frequência, e por quê? Compartilhe nos comentários abaixo – adoraríamos ouvir seus pensamentos!

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.