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?
- Devo usar classes LINQ ou Builder ao fazer query de documentos?
- Por que certas expressões LINQ ou Builder não são suportadas?
- Quais tipos de objetos podem ser serializados?
- Qual é a diferença entre o driver .NET/C# e o provedor do MongoDB Entity Framework Core?
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.
Por que estou recebendo erros ao conectar ao MongoDB?
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.
Como funciona o Pooling de conexão no driver .NET/C#?
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. O diagrama a seguir ilustra uma exibição de alto nível de como o MongoClient
gerencia um pool de conexões:
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.
Por que o driver lança um tempo limite durante a seleção do servidor?
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çará uma exceção de tempo limite de seleção de 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:
O tempo limite de seleção do servidor (30000 ms).
Os seletores de servidor considerados (
CompositeServerSelector
contendoAreSessionsSupportedServerSelector
,LatencyLimitingServerSelector
eOperationsCountServerSelector
).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 oHeartbeatException
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 oopenssl s_client
para depurar problemas de certificado relacionados ao TLS/SSL.
Devo usar classes LINQ ou Builder ao fazer query de documentos?
Se você está acostumado a programar em C#, considere usar LINQ por ser semelhante à programação em C# nativo. Se você tiver experiência anterior com outros drivers MongoDB, considere usar classes Builder devido à sua consistência com outros drivers.
Sugerimos experimentar as duas abordagens para determinar o mecanismo mais adequado para suas finalidades.
Por que certas expressões LINQ ou Builder não são suportadas?
Cada expressão LINQ ou Builder deve estar disponível na API de query. Isso nem sempre é possível pelos seguintes motivos:
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.
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:
Tente configurar o novo LINQ3 provider. O fornecedor LINQ3 contém muitas correções e novas funcionalidades sobre o fornecedor LINQ2 .
Use o MongoDB C# Analyzer para analisar suas expressões.
Tente simplificar sua query sempre que possível.
Forneça uma query como uma string
BsonDocument
ou JSON. Todas as classes de definição de driver, comoFilterDefinition
,ProjectionDefinition
ePipelineDefinition
oferecem suporte à conversão implícita deBsonDocument
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 referência ao campo _id
, 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 definições de string BsonDocument
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 }"));
Quais tipos de objetos podem ser serializados?
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.
Qual é a diferença entre o driver .NET/C# e o provedor do MongoDB Entity Framework Core?
O driver .NET/C# é uma biblioteca que expõe a funcionalidade do MongoDB diretamente e inclui um provedor LINQ com projeções, operações de grupo e mapeamento flexível. O driver inclui recursos como os seguintes:
Transações
Operações em massa
Queries LINQ
Operações que modificam diretamente o banco de dados de dados
Operações de agregação
Mapeamento personalizado
O fornecedor Entity Framework Core Core permite que você use o Entity Framework Core Core da Microsoft com o MongoDB em seus aplicativos .NET/C#. O fornecedor do Entity Framework Core Core oferece suporte ao controle de alterações, operações LINQ baseadas em entidade e modelagem familiar aos usuários do Entity Framework Core. O fornecedor inclui funcionalidades como as seguintes:
Rastreamento inteligente de objeto
Operações LINQ baseadas em entidade
Modelagem e mapeamento do Entity Framework com a API fluente
Atualizações automáticas do banco de dados de dados por meio do acompanhamento de alterações