Menu Docs

Página inicial do DocsDesenvolver aplicaçõesMongoDB DriversC#/.NET

Perguntas frequentes

Nesta página

  • Por que estou recebendo erros ao conectar ao MongoDB?
  • Como funciona o Pooling de conexão no driver .NET/C#?
  • Por que o driver lança um tempo limite durante a seleção do servidor?
  • Por que certas expressões LINQ ou Builder não são suportadas?
  • Quais tipos de objetos podem ser serializados?

Esta página contém perguntas frequentes e suas respostas correspondentes.

Dica

Se você não conseguir encontrar uma resposta para seu problema nesta página, consulte a página Problemas e ajuda para ver as próximas etapas e mais recursos.

Se você tiver problemas para se conectar a um sistema do MongoDB, consulte o Guia de Solução de Problemas de Conexão para obter possíveis soluções.

Cada instância do MongoClient tem um pool de conexão embutida para cada servidor em sua topologia MongoDB. Os pools de conexão abrem soquetes sob demanda para dar suporte a operações simultâneas do MongoDB em seu aplicativo multithread.

O tamanho máximo de cada conjunto de conexões é definido pela opção MaxConnectionPoolSize, que padroniza para 100. Se o número de conexões em uso com um servidor atingir o valor de MaxConnectionPoolSize, a próxima solicitação para esse servidor aguardará até que uma conexão fique disponível.

Além dos soquetes necessários para oferecer suporte aos threads do aplicativo, cada instância MongoClient abre dois soquetes adicionais por servidor na topologia do MongoDB para monitorar o estado do servidor. Por exemplo, um cliente conectado a um conjunto de réplicas de três nós abre seis soquetes de monitoramento. Se o aplicativo usar a configuração padrão para MaxConnectionPoolSize e executar query apenas do nó primário (padrão), poderá haver no máximo 106 conexões totais em uso. Se o aplicativo usar umapreferência de leitura para executar query dos nós secundários, essas pools de conexões crescerão e poderá haver um total 306 conexões.

Para oferecer suporte a um grande número de threads simultâneos do MongoDB em um processo, você pode aumentar MaxConnectionPoolSize.

O driver tem uma fila de espera que limita o número de threads que podem aguardar uma conexão. O tamanho da fila de espera é determinado pela opção WaitQueueMultiple, que é padronizada em 5. Para calcular o tamanho máximo da fila de espera, o driver multiplica WaitQueueMultiple por MaxConnectionPoolSize. Se você utilizar o valor padrão para cada opção, o tamanho da fila de espera será 500. Você também pode definir o tamanho da fila de espera especificando a opção WaitQueueSize, que substitui as outras configurações. No entanto, não recomendamos alterar o tamanho da fila de espera padrão.

Os pools de conexões têm taxa limitada. A configuração MaxConnecting determina o número de conexões que o grupo pode criar em paralelo a qualquer momento. Por exemplo, se o valor de MaxConnecting for 2, o terceiro thread que tenta fazer check-out simultâneo de uma conexão terá êxito somente em um dos seguintes casos:

  • Uma das duas primeiras threads termina criando uma conexão.

  • Uma conexão existente é verificada novamente no pool.

  • A capacidade do driver de reutilizar conexões existentes melhora devido aos limites de taxa na criação de conexões.

Você pode definir o número mínimo de conexões simultâneas para cada servidor usando a opção MinConnectionPoolSize, cujo padrão é 0. O pool de ligações será inicializado com este número de tomadas. Se os erros fizerem com que algum soquete seja fechado e o número total de soquetes (em uso e ociosos) cair abaixo do mínimo, o driver abrirá mais soquetes até que o número atinja o mínimo.

Você pode definir o número máximo de milissegundos que uma conexão pode permanecer ociosa no grupo utilizando a opção MaxConnectionIdleTime. Quando uma conexão fica inativa por MaxConnectionIdleTime, o driver a remove. Esta opção tem como padrão 10 minutos. Se o tamanho do grupo estiver abaixo de MinConnectionPoolSize, o driver removerá e substituirá a conexão ociosa.

MongoClient também tem a opção MaxConnectionLifeTime, que especifica o período de tempo, 30 minutos por padrão, que uma conexão pode ser agrupada antes de expirar.

A seguinte configuração padrão para um MongoClient funciona para a maioria dos aplicativos:

var client = new MongoClient("<connection string>");

Crie um cliente uma vez para cada processo e reutilize-o para todas as operações. É um erro comum criar um novo cliente para cada solicitação, o que é muito ineficiente.

Não há nenhuma maneira compatível de encerrar um MongoClient no driver.

Cada operação de driver exige que você escolha um servidor íntegro que atenda aos critérios de seleção de servidor . Se você não selecionar um servidor apropriado dentro do tempo limite de seleção de servidor , o driver lança uma exceção de tempo limite de seleção do servidor. A exceção parece semelhante ao seguinte:

A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }.
Client view of cluster state is
{
ClusterId : "1",
Type : "Unknown",
State : "Disconnected",
Servers :
[{
ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }",
EndPoint: "Unspecified/localhost:27017",
ReasonChanged: "Heartbeat",
State: "Disconnected",
ServerVersion: ,
TopologyVersion: ,
Type: "Unknown",
HeartbeatException: "<exception details>"
}]
}.

A mensagem de erro consiste em várias partes:

  1. O tempo limite de seleção do servidor (30000 ms).

  2. Os seletores de servidor considerados (CompositeServerSelector contendo AreSessionsSupportedServerSelector, LatencyLimitingServerSelector e OperationsCountServerSelector).

  3. A visão atual do driver da topologia do cluster. A lista de servidores que o driver conhece é uma parte fundamental dessa visualização. Cada descrição de servidor contém uma descrição exaustiva de seu estado atual, incluindo informações sobre um endpoint, uma versão de servidor, um tipo de servidor e seu estado de integridade atual. Se o servidor encontrar problemas ao relatar sua integridade, HeartbeatException conterá a exceção da última pulsação com falha. Analisar o HeartbeatException em cada nó de cluster pode auxiliar no diagnóstico da maioria dos problemas de seleção do servidor. As seguintes exceções de batimentos cardíacos são comuns:

    • No connection could be made because the target machine actively refused it: o driver não pode ver este nó do cluster. Isso pode ocorrer porque o nó do cluster falhou, um firewall está impedindo que o tráfego de rede atinja o nó ou a porta do cluster ou algum outro erro de rede está impedindo que o tráfego seja roteado com êxito para o nó do cluster.

    • Attempted to read past the end of the stream: Este erro acontece quando o driver não pode se conectar aos nós de cluster devido a um erro de rede, firewall configurado incorretamente ou outro problema de rede. Para resolver essa exceção, certifique-se de que todos os nós de cluster estejam acessíveis. Esse erro geralmente ocorre quando o endereço IP da máquina cliente não está configurado na Lista de Acesso IPs do Atlas, que pode ser encontrada na guia Network Access do seu Projeto Atlas.

    • The remote certificate is invalid according to the validation procedure: esse erro normalmente indica um problema relacionado ao TLS/SSL, como um certificado expirado/inválido ou uma CA raiz não confiável. Você pode usar ferramentas como o openssl s_client para depurar problemas de certificado relacionados ao TLS/SSL.

Cada expressão LINQ ou Builder deve estar disponível na API de query. Isso nem sempre é possível pelos seguintes motivos:

  1. Você está tentando usar um recurso .NET/C# que não tem uma representação MongoDB equivalente. Por exemplo, .NET/C# e MongoDB têm semântica diferente em torno de colações.

  2. O driver não oferece suporte a uma transformação específica de LINQ ou expressão do Builder em MQL (MongoDB Query Language). Isso pode ocorrer porque a query fornecida não tem tradução MQL ou porque um recurso ainda não foi implementado no driver.

Se você receber uma mensagem de exceção Unsupported filter ... ou Expression not supported ..., tente as seguintes etapas:

  1. Tente configurar o novo LINQ3 provider. O3 fornecedor LINQ contém muitas correções e novas funcionalidades sobre o2 fornecedor LINQ .

  2. Use o MongoDB Analyzer para analisar suas expressões.

  3. Tente simplificar sua query sempre que possível.

  4. Forneça uma query como uma string BsonDocument ou JSON. Todas as classes de definição de driver, como FilterDefinition, ProjectionDefinitione PipelineDefinition oferecem suporte à conversão implícita de BsonDocument ou string JSON. Por exemplo, os seguintes filtros são equivalentes quando usados em uma query ou agregação:

FilterDefinition<Entity> typedFilter = Builders<Entity>.Filter.Eq(e => e.A, 1);
FilterDefinition<Entity> bsonFilter = new BsonDocument {{ "a", 1 }};
FilterDefinition<Entity> jsonFilter = "{ a : 1 }";

Observação

Se você usar BsonDocument ou string JSON, então BsonClassMap, os atributos de serialização BSON e as convenções de serialização não são levados em conta na API de query. Os nomes dos campos devem corresponder aos nomes e letras armazenados pelo servidor. Por exemplo, ao fazer _id referência ao campo , você deverá referir-se a ele usando _id em BsonDocument ou definições de string JSON. Da mesma forma, se um documento tiver um campo FirstName anotado com [BsonElement("first_name")], você deverá referir-se a ele como first_name nas BsonDocument definições de string ou JSON.

Você pode combinar os formulários brutos e digitados na mesma query, pois o seguinte código demonstra:

FilterDefinition<Entity> filter = Builders<Entity>.Filter
.And(Builders<Entity>.Filter
.Eq(e => e.A, 1), BsonDocument
.Parse("{ b : 2 }"));

O ObjectSerializer permite serialização e desserialização somente dos tipos que são considerados seguros. Ao construir um ObjectSerializer, você pode passar um delegado do tipo Func<Type, bool>. Este delegado aceita um tipo de objeto e retorna um valor booleano indicando se o tipo é seguro para serialização.

Na maioria dos casos, você deve passar no delegado ObjectSerializer.DefaultAllowedTypes(). Este método retorna verdadeiro para vários tipos de estruturas conhecidas que consideramos seguras. Para serializar tipos personalizados, crie uma expressão booleana que avalia para true para os tipos que você deseja incluir. Em seguida, adicione esta expressão ao final do delegado que você passa para o construtor ObjectSerializer.

No exemplo abaixo, o ObjectSerializer serializará e desserializará qualquer tipo permitido pelo ObjectSerializer.DefaultAllowedTypes() ou cujo nome completo comece com "MyNamespace":

var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type)
|| type.FullName.StartsWith("MyNamespace"));
BsonSerializer.RegisterSerializer(objectSerializer);

Para permitir que tipos anônimos sejam serializados, adicione a expressão boolean type.FullName.StartsWith("<>f__AnonymousType")) ao seu delegado, como indicado no exemplo abaixo:

var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type)
|| type.FullName.StartsWith("<>f__AnonymousType"));
BsonSerializer.RegisterSerializer(objectSerializer);

Você deve criar e registrar seu ObjectSerializer no início do seu programa, antes de fazer qualquer outra coisa.

← Criptografia em execução