Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-2963

And filter with $near translates to invalid MongoDb query

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 2.11.0
    • Affects Version/s: 2.10.1
    • Component/s: Builders
    • None
    • Environment:
      Windows

      If we create multiple geo conditions on the same field in one query, and one condition is the near operator. The driver don't translate this to a correct MongoDb query. The following code demonstrate the behaviour. And the result and exception message is as comments.

      using MongoDB.Bson;
      using MongoDB.Bson.Serialization;
      using MongoDB.Driver;
      using MongoDB.Driver.GeoJsonObjectModel;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;namespace MongoDbJira
      {
          class Program
          {
              static void Main(string[] args)
              {
                  var client = new MongoClient("mongodb://localhost");
                  var database = client.GetDatabase("testdb");
                  database.DropCollection("test");
                  var collection = database.GetCollection<BsonDocument>("test");
                  var indexModel = new CreateIndexModel<BsonDocument>(new IndexKeysDefinitionBuilder<BsonDocument>().Geo2DSphere("geoField"));
                  collection.Indexes.CreateOne(indexModel);            collection.InsertOne(BsonDocument.Parse("{'geoField':{'type':'Point','coordinates':[18.07309566753327, 59.31119815301082]}, 'name':'A'}"));
                  collection.InsertOne(BsonDocument.Parse("{'geoField':{'type':'Point','coordinates':[18.031779179282793 59.31869226401174]} 'name':'B'}"));
                  
                  var filterDefinitions = new List<FilterDefinition<BsonDocument>>();
                  filterDefinitions.Add(Builders<BsonDocument>.Filter.GeoWithinBox("geoField", 18.02768052426505, 59.302264601734144, 18.103211530124426, 59.32407863571196));
                  filterDefinitions.Add(Builders<BsonDocument>.Filter.Near("geoField", new GeoJsonPoint<GeoJson2DCoordinates>(new GeoJson2DCoordinates(18.07176, 59.31395)), 500));
                  var filterDefinition = Builders<BsonDocument>.Filter.And(filterDefinitions);
                  var failingFilterDefinitionAsString = filterDefinition.Render(BsonSerializer.SerializerRegistry.GetSerializer<BsonDocument>(), BsonSerializer.SerializerRegistry).ToString();
                  Console.WriteLine(failingFilterDefinitionAsString); //{ "geoField" : { "$geoWithin" : { "$box" : [[18.027680524265051, 59.302264601734144], [18.103211530124426, 59.324078635711963]] }, "$near" : { "$geometry" : { "type" : "Point", "coordinates" : [18.071760000000001, 59.313949999999998] }, "$maxDistance" : 500.0 } } }            try
                  {
                      var failingFindResult = collection.Find(filterDefinition).ToList();
                  }
                  catch (Exception e)
                  {
                      Console.WriteLine(e.Message); //Command find failed: can't parse extra field: $near: { $geometry: { type: "Point", coordinates: [ 18.07307303636145, 59.31128165641481 ] }, $maxDistance: 500.0 }.
                  }
                  var myFilterBuilder = new StringBuilder();
                  myFilterBuilder.Append("{$and:[");
                  for (int i = 0; i < filterDefinitions.Count; i++)
                  {
                      if (i > 0)
                      {
                          myFilterBuilder.Append(",");
                      }
                      myFilterBuilder.Append(filterDefinitions.ElementAt(i).Render(BsonSerializer.SerializerRegistry.GetSerializer<BsonDocument>(), BsonSerializer.SerializerRegistry).ToString());
                  }
                  myFilterBuilder.Append("]}");
                  var successfulFilterDefintionAsString = BsonSerializer.Deserialize<BsonDocument>(myFilterBuilder.ToString());
                  Console.WriteLine(successfulFilterDefintionAsString); //{{ "$and" : [{ "geoField" : { "$geoWithin" : { "$box" : [[18.027680524265051, 59.302264601734144], [18.103211530124426, 59.324078635711963]] } } }, { "geoField" : { "$near" : { "$geometry" : { "type" : "Point", "coordinates" : [18.071760000000001, 59.313949999999998] }, "$maxDistance" : 500.0 } } }] }}            var successfulFindResult = collection.Find(successfulFilterDefintionAsString).ToList();
                  Console.WriteLine(successfulFindResult[0]["name"]); //A            Console.ReadKey();
              }
          }
      }
      
      

      The attached image describe the geometry objects used in this example.

        1. map.png
          465 kB
          _daniel@prodev.se

            Assignee:
            dmitry.lukyanov@mongodb.com Dmitry Lukyanov (Inactive)
            Reporter:
            daniel.moqvist@knowit.se daniel moqvist
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: