[CSHARP-3912] Cannot find serializer for mtest.Category.Aggregate([{ "$match" : { "Published" : true } }]) Created: 18/Oct/21  Updated: 27/Oct/23  Resolved: 20/Oct/21

Status: Closed
Project: C# Driver
Component/s: LINQ3
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Unknown
Reporter: Alexey Anohin Assignee: Robert Stam
Resolution: Works as Designed Votes: 0
Labels: LINQ
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

query = query.Where(entry => entry.Published);

{
  $jsonSchema: {
    bsonType: 'object',
    required: [
      'Name',
      'CategoryTemplateId',
      'ParentCategoryId',
      'PictureId',
      'PageSize',
      'AllowCustomersToSelectPageSize',
      'ShowOnHomepage',
      'IncludeInTopMenu',
      'SubjectToAcl',
      'LimitedToStores',
      'Published',
      'Deleted',
      'DisplayOrder',
      'CreatedOnUtc',
      'UpdatedOnUtc'
    ],
    properties: {
      Name: {
        bsonType: 'string',
        maxLength: 400
      },
      MetaKeywords: {
        bsonType: 'string',
        maxLength: 400
      },
      MetaTitle: {
        bsonType: 'string',
        maxLength: 400
      },
      PriceRanges: {
        bsonType: 'string',
        maxLength: 400
      },
      PageSizeOptions: {
        bsonType: 'string',
        maxLength: 200
      },
      Description: {
        bsonType: 'string',
        maxLength: 2147483647
      },
      CategoryTemplateId: {
        bsonType: 'int'
      },
      MetaDescription: {
        bsonType: 'string',
        maxLength: 2147483647
      },
      ParentCategoryId: {
        bsonType: 'int'
      },
      PictureId: {
        bsonType: 'int'
      },
      PageSize: {
        bsonType: 'int'
      },
      AllowCustomersToSelectPageSize: {
        bsonType: 'bool'
      },
      ShowOnHomepage: {
        bsonType: 'bool'
      },
      IncludeInTopMenu: {
        bsonType: 'bool'
      },
      SubjectToAcl: {
        bsonType: 'bool'
      },
      LimitedToStores: {
        bsonType: 'bool'
      },
      Published: {
        bsonType: 'bool'
      },
      Deleted: {
        bsonType: 'bool'
      },
      DisplayOrder: {
        bsonType: 'int'
      },
      CreatedOnUtc: {
        bsonType: 'date'
      },
      UpdatedOnUtc: {
        bsonType: 'date'
      }
    }
  }
}

An exception of type 'System.InvalidOperationException' occurred in MongoDB.Driver.dll but was not handled in user code: 'Cannot find serializer for mtest.Category.Aggregate([{ "$match" : { "Published" : true } }]).'   at MongoDB.Driver.Linq.Linq3Implementation.Serializers.KnownSerializers.KnownSerializersRegistry.GetSerializer(Expression expression, IBsonSerializer defaultSerializer)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ConstantExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, ConstantExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MethodTranslators.AnyMethodToAggregationExpressionTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MethodCallExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.TranslateUsingAggregationOperators(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.Translate(TranslationContext context, Expression expression, Boolean exprOk)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ExpressionToFilterTranslator.TranslateLambda(TranslationContext context, LambdaExpression lambdaExpression, IBsonSerializer parameterSerializer)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.WhereMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.OrderByMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.OrderByMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToExecutableQueryTranslators.ExpressionToExecutableQueryTranslator.Translate[TDocument,TOutput](MongoQueryProvider`1 provider, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.MongoQuery`2.Execute()
   at MongoDB.Driver.Linq.Linq3Implementation.MongoQuery`2.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)



 Comments   
Comment by Alexey Anohin [ 27/Oct/21 ]

Hi, Robert! Any conclusions? Is there a chance to include something like this in the next release?

Comment by Alexey Anohin [ 21/Oct/21 ]

We can build a JOIN statement that is the same as EXISTS operator (http://sqlfiddle.com/#!18/ad2ab/2), e.g.:

 

select * from products p
 where exists (
 select * from storemapping sm
 where sm.storeId = 's1' and p.uid = sm.entityId and sm.entityName = 'product');
select p.* 
 from products p 
 inner join storemapping sm on p.uid = sm.entityId and sm.entityName = 'product' and sm.storeId = 's1'

 

So, a LINQ query with subquery can be translated like that (https://mongoplayground.net/p/3Ez-2j6VM1K):

prosucts
    .AsQueryable()
    .Where(p => 
        storemapping
            .AsQueryable()
            .Any(sm => sm.storeId == "s1" && p.uid == sm.entityId)
    );

 

db.products.aggregate([
  {
    $lookup: {
      from: "storemapping",
      localField: "uid",
      foreignField: "entityId",
      let: {
        productId: "$uid"
      },
      as: "storemapping",
      pipeline: [
        {
          $match: {
            "$and": [
              {
                storeId: "s1"
              },
              {
                $expr: {
                  $eq: [
                    "$entityId",
                    "$$productId"
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  },
  {
    $match: {
      storemapping: {
        $ne: []
      }
    }
  },
  {
    $project: {
      storemapping: 0
    }
  }
])

 

 

Comment by Robert Stam [ 20/Oct/21 ]

Do you have a particular MQL in mind?

$lookup is more like a "join" than like a "sub query".

Comment by Alexey Anohin [ 20/Oct/21 ]

What about subqueries via $lookup? Is it still seems impossible?

Comment by Robert Stam [ 20/Oct/21 ]

It is the nature of LINQ providers that not all LINQ expressions that compile can be translated by the LINQ provider.

The C# driver LINQ provider has to translate the LINQ query to an equivalent MQL query.

In this case, that doesn't seem possible. MQL doesn't support subqueries like that.

Comment by Alexey Anohin [ 19/Oct/21 ]

You're right. I guess the actual issue is with a subquery of the complex query. I've tried something like this, and it doesn't work:

 

var collection = database.GetCollection<C>("csharp3912");
var collection2 = database.GetCollection<C>("csharp3912-2");
var q = from e1 in collection.AsQueryable()
        where collection2.AsQueryable(null).Any(e2 => e2.Published)
        select e1;

 

Message: 
MongoDB.Driver.Linq.Linq3Implementation.ExpressionNotSupportedException : Expression not supported: Tests10191722.csharp3912-2.Aggregate([]).Any(e2 => e2.Published).  
 
Stack Trace: 
AnyMethodToAggregationExpressionTranslator.Translate(TranslationContext context, MethodCallExpression expression) line 59
MethodCallExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, MethodCallExpression expression) line 30
ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression) line 61
ExpressionToFilterTranslator.TranslateUsingAggregationOperators(TranslationContext context, Expression expression) line 62
ExpressionToFilterTranslator.Translate(TranslationContext context, Expression expression, Boolean exprOk) line 40
ExpressionToFilterTranslator.TranslateLambda(TranslationContext context, LambdaExpression lambdaExpression, IBsonSerializer parameterSerializer) line 56
WhereMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression) line 39
ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression) line 63
ExpressionToExecutableQueryTranslator.Translate[TDocument,TOutput](MongoQueryProvider`1 provider, Expression expression) line 34
Linq3TestHelpers.Translate[TDocument,TResult](IQueryable`1 queryable) line 54
Linq3TestHelpers.Translate[TDocument,TResult](IMongoCollection`1 collection, IQueryable`1 queryable) line 48
CSharp3910Tests.Where_with_bool_field_should_work() line 37

Comment by Robert Stam [ 18/Oct/21 ]

Thank you for trying the beta version of the new LINQ provider and for reporting this issue.

I am unable to reproduce this issue using only this information:

 query = query.Where(entry => entry.Published);

I guessed at all the missing code and used this code to attempt to reproduce, but the test passes:

[Fact]
public class CSharp3912Tests
{
    [Fact]
    public void Where_with_bool_field_should_work()
    {
        var client = DriverTestConfiguration.Linq3Client;
        var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
        var collection = database.GetCollection<C>("csharp3912");
 
        var queryable = collection.AsQueryable()
            .Where(entry => entry.Published);
 
        var stages = Linq3TestHelpers.Translate(collection, queryable);
        var expectedStages = new[]
        {
            "{ $match : { Published : true } }"
        };
        Linq3TestHelpers.AssertStages(stages, expectedStages);
    }
 
    private class C
    {
        public int Id { get; set; }
        public bool Published { get; set; }
    }
}

Can you please compare this attempt to reproduce to your actual code and provide us with more information to reproduce what you are seeing?
 

Generated at Wed Feb 07 21:46:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.