Consultar no Amazon DocumentDB - Amazon DocumentDB

Consultar no Amazon DocumentDB

Esta seção explica todos os aspectos da consulta com o Amazon DocumentDB.

Consultar documentos

Às vezes, pode ser necessário examinar o inventário da sua loja online para que os clientes possam visualizar e comprar o que você está vendendo. Consultar uma coleção é relativamente fácil, quer você queira todos os documentos na coleção ou apenas os documentos que satisfazem a um critério específico.

Para consultar documentos, use a operação find(). O comando find() tem um único parâmetro do documento que define os critérios a serem usados na escolha dos documentos a serem retornados. A saída de find() é um documento formatado como uma única linha de texto sem quebras de linha. Para formatar o documento de saída para facilitar a leitura, use find().pretty(). Todos os exemplos deste tópico usam .pretty() para formatar a saída.

Os exemplos de código a seguir usam os quatro documentos que você inseriu na coleção example nos dois exercícios anteriores — insertOne() e insertMany() que estão localizados na seção Adicionar documentos de Trabalhando com documentos.

Recuperar todos os documentos em uma coleção

Para recuperar todos os documentos em sua coleção, use a operação find() com um documento de consulta vazio.

A consulta a seguir retorna todos os documentos da coleção example.

db.example.find( {} ).pretty()

Recuperar documentos que correspondem a um valor de campo

Para recuperar todos os documentos que correspondem a um campo e valor, use a operação find() com um documento de consulta que identifica os campos e valores a serem correspondidos.

Usando documentos anteriores, essa consulta retorna todos os documentos em que o campo "Item" será igual a "Pen".

db.example.find( { "Item": "Pen" } ).pretty()

Recuperar documentos que correspondem a um documento incorporado

Para localizar todos os documentos que correspondem a um documento incorporado, use a operação find() com um documento de consulta que especifica o nome do documento incorporado e todos os campos e valores desse documento incorporado.

Ao vincular um documento incorporado, o documento incorporado do documento deve ter o mesmo nome que na consulta. Além disso, os campos e os valores no documento incorporado devem corresponder à consulta.

A consulta a seguir retorna apenas o documento "Poster Paint". Isso ocorre porque a "Caneta" tem valores diferentes para "OnHand" e "MinOnHand", e a "Tinta spray" tem um campo a mais (OrderQnty) que o documento de consulta.

db.example.find({"Inventory": { "OnHand": 47, "MinOnHand": 50 } } ).pretty()

Recuperar documentos que correspondem a um valor de campo em um documento incorporado

Para localizar todos os documentos que correspondem a um documento incorporado, use a operação find() com um documento de consulta que especifica o nome do documento incorporado e todos os campos e valores desse documento incorporado.

Considerando os documentos anteriores, a consulta a seguir usa "notação de pontos" para especificar o documento incorporado e os campos de interesse. Qualquer documento que seja correspondente será retornado, independentemente de quais outros campos possam estar presentes no documento incorporado. A consulta retorna "Poster Paint" e "Spray Paint", pois ambos correspondem aos campos e valores especificados.

db.example.find({"Inventory.OnHand": 47, "Inventory.MinOnHand": 50 }).pretty()

Recuperar documentos que correspondem a uma matriz

Para localizar todos os documentos que correspondem a uma matriz, use a operação find() com o nome da matriz de interesse e todos os valores na matriz. A consulta retorna todos os documentos que têm uma matriz com esse nome, com valores idênticos aos da matriz, e na mesma ordem que na consulta.

A consulta a seguir retorna apenas o documento "Pen", pois o "Poster Paint" tem uma cor adicional (White), e "Spray Paint" tem as cores em ordem diferente.

db.example.find( { "Colors": ["Red","Green","Blue","Black"] } ).pretty()

Recuperar documentos que correspondem a um valor em uma matriz

Para localizar todos os documentos que possuem um valor de matriz específico, use a operação find() com o valor e o nome da matriz de interesse.

db.example.find( { "Colors": "Red" } ).pretty()

A operação anterior retorna todos os três documentos, pois cada um deles tem uma matriz chamada Colors e o valor Red em algum lugar da matriz. Se você especificar o valor "White", a consulta retornará apenas "Tinta de cartaz".

Recuperar documentos usando operadores

A consulta a seguir retorna todos os documentos em que o valor "Inventory.OnHand" é inferior a 50.

db.example.find( { "Inventory.OnHand": { $lt: 50 } } )

Para obter uma lista de operadores de consulta compatíveis, consulte Operadores de consulta e projeção.

Plano de consulta

Como posso ver os executionStats de um plano de consulta?

Ao determinar por que uma consulta está sendo executada mais lentamente do que o esperado, pode ser útil entender quais são os executionStats desse plano de consulta. O executionStats fornece o número de documentos retornados de um estágio específico (nReturned), a quantidade de tempo de execução gasto em cada estágio (executionTimeMillisEstimate) e o tempo necessário para gerar um plano de consulta (planningTimeMillis). É possível determinar os estágios mais demorados de sua consulta para ajudar a concentrar seus esforços de otimização na saída de executionStats, como mostrado nos exemplos de consulta abaixo. No momento, o parâmetro executionStats não é compatível com os comandos delete e update.

nota

O Amazon DocumentDB emula a API do MongoDB 3.6 em um mecanismo de banco de dados criado para fins específicos que utiliza um sistema de armazenamento distribuído, tolerante a falhas e autorrecuperável. Como resultado, os planos de consulta e a saída de explain() podem diferir entre o Amazon DocumentDB e o MongoDB. Os clientes que desejam ter controle sobre seu plano de consulta podem usar o operador $hint para impor a seleção de um índice preferencial.

Execute a consulta que você deseja melhorar com o comando explain() da seguinte forma.

db.runCommand({explain: {query document}}). explain("executionStats").executionStats;

Veja a seguir um exemplo de operação.

db.fish.find({}).limit(2).explain("executionStats");

A saída dessa operação é semelhante à seguinte.

{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.fish", "winningPlan" : { "stage" : "SUBSCAN", "inputStage" : { "stage" : "LIMIT_SKIP", "inputStage" : { "stage" : "COLLSCAN" } } } }, "executionStats" : { "executionSuccess" : true, "executionTimeMillis" : "0.063", "planningTimeMillis" : "0.040", "executionStages" : { "stage" : "SUBSCAN", "nReturned" : "2", "executionTimeMillisEstimate" : "0.012", "inputStage" : { "stage" : "LIMIT_SKIP", "nReturned" : "2", "executionTimeMillisEstimate" : "0.005", "inputStage" : { "stage" : "COLLSCAN", "nReturned" : "2", "executionTimeMillisEstimate" : "0.005" } } } }, "serverInfo" : { "host" : "enginedemo", "port" : 27017, "version" : "3.6.0" }, "ok" : 1 }

Se estiver interessado em ver apenas o executionStats da consulta acima, você pode usar o seguinte comando. Para coleções pequenas, o processador de consultas do Amazon DocumentDB pode optar por não usar um índice se os ganhos de desempenho forem insignificantes.

db.fish.find({}).limit(2).explain("executionStats").executionStats;

Cache do plano de consultas

Para otimizar o desempenho e reduzir a duração do planejamento, o Amazon DocumentDB armazena internamente os planos de consulta em cache. Isso permite que consultas com a mesma forma sejam executadas diretamente usando um plano em cache.

No entanto, esse armazenamento em cache às vezes pode causar um atraso aleatório para a mesma consulta; por exemplo, uma consulta que normalmente leva um segundo para ser executada pode, ocasionalmente, levar dez segundos. Isso ocorre porque, com o tempo, a instância do leitor armazenou em cache várias formas da consulta, consumindo memória. Se você tiver essa lentidão aleatória, não é necessário fazer nada para liberar a memória. O sistema gerenciará o uso da memória para você e, quando a memória atingir um determinado limite, ela será liberada automaticamente.

Explicar os resultados

Se você quiser retornar informações sobre planos de consulta, o Amazon DocumentDB oferece suporte ao modo de verbosidade queryPlanner. Os resultados do explain retornam o plano de consulta selecionado escolhido pelo otimizador em um formato semelhante ao seguinte:

{ "queryPlanner" : { "plannerVersion" : <int>, "namespace" : <string>, "winningPlan" : { "stage" : <STAGE1>, ... "inputStage" : { "stage" : <STAGE2>, ... "inputStage" : { ... } } } } }

As seções a seguir definirão os resultados explain comuns.

Estágio de digitalização e filtragem

O otimizador pode escolher um dos seguintes escaneamentos:

COLLSCAN

Esse estágio é um escaneamento de coleta sequencial.

{ "stage" : "COLLSCAN" }

IXSCAN

Esse estágio verifica as teclas de índice. O otimizador pode recuperar o documento nesse estágio e isso pode resultar em um estágio FETCH anexado posteriormente.

db.foo.find({"a": 1}) { "stage" : "IXSCAN", "direction" : "forward", "indexName" : <idx_name> }

FETCH

Se o otimizador recuperou documentos em um estágio diferente do IXSCAN, o resultado incluirá um estágio FETCH. Por exemplo, a consulta IXSCAN acima pode resultar em uma combinação dos estágios FETCH e IXSCAN:

db.foo.find({"a": 1}) { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "indexName" : <idx_name> } }

O IXONLYSCAN verifica somente a chave de índice. Criar índices compostos não evitará o FETCH.

Interseção de índices

IXAND

O Amazon DocumentDB pode incluir um estágio IXAND com uma matriz InputStages do IXSCAN se puder utilizar a interseção de índices. Por exemplo, podemos ver resultados como:

{ "stage" : "FETCH", "inputStage" : { "stage" : "IXAND", "inputStages" : [ { "stage" : "IXSCAN", "indexName" : "a_1" }, { "stage" : "IXSCAN", "indexName" : "b_1" } ] } }

União de índices

IXOR

Semelhante à interseção de índices, o Amazon DocumentDB pode incluir o estágio IXOR com uma matriz inputStages para o operador $or.

db.foo.find({"$or": [{"a": {"$gt": 2}}, {"b": {"$lt": 2}}]})

Para a consulta acima, a saída de explicação pode ter a seguinte aparência:

{ "stage" : "FETCH", "inputStage" : { "stage" : "IXOR", "inputStages" : [ { "stage" : "IXSCAN", "indexName" : "a_1" }, { "stage" : "IXSCAN", "indexName" : "b_1" } ] } }

Interseção/união de vários índices

O Amazon DocumentDB pode combinar vários estágios de interseção ou união de índices e, em seguida, buscar o resultado. Por exemplo:

{ "stage" : "FETCH", "inputStage" : { "stage" : "IXOR", "inputStages" : [ { "stage" : "IXSCAN", ... }, { "stage" : "IXAND", "inputStages" : [ { "stage" : "IXSCAN", ... }, { "stage" : "IXSCAN", ... } ] } ] } }

O uso de estágios de interseção ou união de índices não é afetado pelo tipo de índice (esparso, composto, etc.).

Índice composto

O uso do índice composto do Amazon DocumentDB não está limitado aos subconjuntos iniciais dos campos indexados; ele pode usar o índice com a parte do sufixo, mas pode não ser muito eficiente.

Por exemplo, o índice composto de { a: 1, b: -1 } pode oferecer suporte às três consultas abaixo:

db.orders.find( { a: 1 } } )

db.orders.find( { b: 1 } } )

db.orders.find( { a: 1, b: 1 } } )

Fase de classificação

Se houver um índice na(s) chave(s) de classificação solicitada(s), o Amazon DocumentDB poderá usar o índice para obter a ordem. Nesse caso, o resultado não incluirá um estágio SORT, mas sim um estágio IXSCAN. Se o otimizador preferir uma classificação simples, ele incluirá um estágio como este:

{ "stage" : "SORT", "sortPattern" : { "a" : 1, "b" : -1 } }

Fase de grupos

O Amazon DocumentDB oferece suporte a duas estratégias de grupo diferentes:

  • SORT_AGGREGATE: agregação de classificação no disco.

  • HASH_AGGREGATE: agregação de hash na memória.