[CSHARP-2463] $facet is not deserializing Created: 24/Dec/18  Updated: 27/Oct/23  Resolved: 30/Jan/19

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

Type: Task Priority: Trivial - P5
Reporter: Murilo Kunze Assignee: Wan Bachtiar
Resolution: Works as Designed Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate

 Description   

I'm trying to run this command:

var applicationsPipeline = PipelineDefinition<AffiliateRecord, List<ApplicationRecord>>.Create(new IPipelineStageDefinition[] {
    PipelineStageDefinitionBuilder.Match<AffiliateRecord>(filter),
    PipelineStageDefinitionBuilder.Unwind<AffiliateRecord, AffiliateRecord>("Applications"),
    PipelineStageDefinitionBuilder.Match<AffiliateRecord>(matchApplications),
    PipelineStageDefinitionBuilder.ReplaceRoot<AffiliateRecord, List<ApplicationRecord>>(x => x.Applications),
    PipelineStageDefinitionBuilder.Skip<List<ApplicationRecord>>(offset),
    PipelineStageDefinitionBuilder.Limit<List<ApplicationRecord>>(limit),
});
 
var applicationsFacet = AggregateFacet.Create("applications", applicationsPipeline);
 
var aggregate = collection
    .Aggregate()
    .Facet(applicationsFacet, ...);
 
var facetResult = await aggregate.SingleOrDefaultAsync();

but I'm getting this error:

System.FormatException: Cannot deserialize a 'List<ApplicationRecord>' from BsonType 'Document'.

What am I missing?



 Comments   
Comment by Wan Bachtiar [ 18/Jan/19 ]

which makes me think that ReplaceRoot has some kind of bug because it forces me to set TOutput as List<ApplicationRecord> instead of ApplicationRecord.

Hi Murilo,

I think you meant the other way around (also based on your own snippet). You need to specify TOutput as ApplicationRecord instead of List<ApplicationRecord>.

This is not a bug in the driver, but an expected behaviour. The $unwind stage outputs a single `ApplicationRecord` and not an array anymore.

For example, from:

{ 
    Applications: [
        {record:1}, {record:2}
    ]
}

to:

{ 
    Applications: {record:1} 
}
 
{ 
    Applications: {record:2} 
}

The $replaceRoot stage then only promotes the singular `ApplicationRecord` to root. i.e. {{

{record:1}

}}.

The deserialise error is also the result of the mismatched type of List<ApplicationRecord>.

Regards,
Wan.

Comment by Murilo Kunze [ 26/Dec/18 ]

I was able to make it work like this:

            var applicationsPipeline = PipelineDefinition<AffiliateRecord, ApplicationRecord>.Create(new IPipelineStageDefinition[] {
                PipelineStageDefinitionBuilder.Match<AffiliateRecord>(filter),
                PipelineStageDefinitionBuilder.Unwind<AffiliateRecord>(x => x.Applications),
                PipelineStageDefinitionBuilder.Match<BsonDocument>(new BsonDocument("$and", and)),
                PipelineStageDefinitionBuilder.ReplaceRoot<BsonDocument, ApplicationRecord>("$Applications"),
                PipelineStageDefinitionBuilder.Skip<ApplicationRecord>(offset),
                PipelineStageDefinitionBuilder.Limit<ApplicationRecord>(limit)
            });
 

which makes me think that ReplaceRoot has some kind of bug because it forces me to set TOutput as List<ApplicationRecord> instead of ApplicationRecord.

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