The LINQ3 driver is using '$getField' for projections in some circumstances, even though it shouldn't if the server does not support it yet. Here's a small unit test to showcase the problem:
[Test] public void reproduce_linq_v3_error_for_number_like_projection() { var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27017/?replicaSet=rs0"); // using V2 fixes the problem settings.LinqProvider = LinqProvider.V3; var client = new MongoClient(settings); var database = client.GetDatabase("some-database"); var collection = database.GetCollection<BsonDocument>("some-collection"); // changing this to some non-numerical value like "a" also fixes the problem string projectedField = "1"; // Tested against server versions 4.2.19 and 4.4.3, the next line produces the following error: // "Command aggregate failed: Invalid $project :: caused by :: Unknown expression $getField" // Which makes sense because $getField was introduced in server version 5.0.0 var result = (from doc in collection.AsQueryable() select doc[projectedField]).ToList(); }
The full stacktrace looks as follows:
fail: TPP.Core.Commands.CommandProcessor[0] An exception occured while executing command 'balance'. User: User(console-admin/admin), Original text: tokens MongoDB.Driver.MongoCommandException: Command aggregate failed: Invalid $project :: caused by :: Unknown expression $getField. at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ProcessResponse(ConnectionId connectionId, CommandMessage responseMessage) at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ExecuteAsync(IConnection connection, CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocolAsync[TResult](IWireProtocol`1 protocol, ICoreSession session, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableReadOperationExecutor.ExecuteAsync[TResult](IRetryableReadOperation`1 operation, RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.ReadCommandOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.AggregateOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.AggregateOperation`1.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken) at MongoDB.Driver.OperationExecutor.ExecuteReadOperationAsync[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperationAsync[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.AggregateAsync[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToExecutableQueryTranslators.ExecutableQuery`3.ExecuteAsync(IClientSessionHandle session, CancellationToken cancellationToken) at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken) at TPP.Persistence.MongoDB.PersistedReservedMoneyCheckers.PinballReservedTokens(User user) in S:\projects\tpp-core\TPP.Persistence.MongoDB\PersistedReservedMoneyCheckers.cs:line 28 at TPP.Persistence.MongoDB.PersistedReservedMoneyCheckers.AllDatabaseReservedTokens(User user) in S:\projects\tpp-core\TPP.Persistence.MongoDB\PersistedReservedMoneyCheckers.cs:line 22 at TPP.Persistence.ReserveCheckersBank`1.<>c__DisplayClass3_0.<<GetReservedMoney>b__0>d.MoveNext() in S:\projects\tpp-core\TPP.Persistence\IBank.cs:line 190 --- End of stack trace from previous location --- at TPP.Persistence.ReserveCheckersBank`1.GetReservedMoney(T user) in S:\projects\tpp-core\TPP.Persistence\IBank.cs:line 191 at TPP.Persistence.ReserveCheckersBank`1.GetAvailableMoney(T user) in S:\projects\tpp-core\TPP.Persistence\IBank.cs:line 197 at TPP.Core.Commands.Definitions.UserCommands.CheckBalance(CommandContext context) in S:\projects\tpp-core\TPP.Core\Commands\Definitions\UserCommands.cs:line 109 at TPP.Core.Commands.CommandProcessor.Process(String commandName, IImmutableList`1 args, Message message) in S:\projects\tpp-core\TPP.Core\Commands\CommandProcessor.cs:line 84