[CSHARP-4729] Using GeoJson2DCoordinates in a LINQ projection causes a System.NotSupportedException Created: 21/Jul/23  Updated: 31/Jul/23

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

Type: Bug Priority: Unknown
Reporter: David Wolsey Assignee: Boris Dogadov
Resolution: Unresolved Votes: 0
Labels: LINQ3
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Summary

Using MongoDB.Driver.GeoJsonObjectModel.GeoJson2DCoordinates in a LINQ projection causes a System.NotSupportedException.

This works as expected in version 2.18.0 of the driver but fails in 2.19 and 2.20.

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

2.19.0 and 2.20.0.

How to Reproduce

See here for a reproduction. 

Given the following types

 

public class PlaceEntity
{
    public string? Name { get; set; }
    public GeoJson2DCoordinates? Location { get; set; }
}
 
public class PlaceHeader
{
    public string? Name { get; set; }
    public double? Latitude { get; set; }
    public double? Longitude { get; set; }
} 

and the following code

 

 

 

private readonly IMongoCollection<PlaceEntity> _places;
public async Task<List<PlaceEntity>> GetPlaceEntities()
{
    return await _places.Find(Builders<PlaceEntity>.Filter.Empty).ToListAsync();
}
public async Task<List<PlaceHeader>> GetPlaceHeaders()
{
    return await _places
        .Find(Builders<PlaceEntity>.Filter.Empty)
        .Project(x => new PlaceHeader
        {
            Name = x.Name,
            Latitude = x.Location != null ? x.Location.X : null,
            Longitude = x.Location != null ? x.Location.Y : null,
        })
        .ToListAsync();
}

calling GetPlaceEntities() works, but calling GetPlaceHeaders() causes the following exception:

System.NotSupportedException: Serializer for MongoDB.Driver.GeoJsonObjectModel.GeoJson2DCoordinates must implement IBsonDocumentSerializer to be used with LINQ.

Is it expected that the GeoJson types can't be used in LINQ projections when using the V3 LINQ provider? These projections work as expected with the V2 provider.

 

 



 Comments   
Comment by David Wolsey [ 26/Jul/23 ]

Hi boris.dogadov@mongodb.com.

Performing the projection client-side is fine for our current use-case so we'll do that and keep an eye on this ticket for any future server-side support. Thanks for looking into it.

Comment by Boris Dogadov [ 25/Jul/23 ]

Thank you for raising this issue david.wolsey@gmail.com 

Projections involving GeoJson objects are actually executed on the client side with LINQ2 provider. LINQ3 introduced a different approach, where client side projections are not supported, and the whole expression is executed on server side.
We will evaluate supporting server side queries involving GeoJson objects in LINQ3. Please follow this ticket for further updates.

In this example the client side projection has to be done explicitly.
For example adding ToEnumerable() method with sync API,  or breaking the query to several statements with async API:

Sync:

coll.Find(Builders<PlaceEntity>.Filter.Empty)
      .ToEnumerable()
      .Select(x => new PlaceHeader()
      {
         Name = x.Name,
         Latitude = x.Location != null ? x.Location.X : null,
         Longitude = x.Location != null ? x.Location.Y : null,
       }}
      .ToList();

Async:

 var cursor = await coll.FindAsync(Builders<PlaceEntity>.Filter.Empty);
 var items = await cursor.ToListAsync();
 var itemsProjected = items.Select(x => new PlaceHeader()
 {
  Name = x.Name,
  Latitude = x.Location != null ? x.Location.X : null,
  Longitude = x.Location != null ? x.Location.Y : null,
 });

Comment by PM Bot [ 21/Jul/23 ]

Hi david.wolsey@gmail.com, thank you for reporting this issue! The team will look into it and get back to you soon.

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