Hello,
After upgrading to 2.1.1, we've noticed a problem with one of the oldest LINQ queries in our system which no longer filtered down a set of results to what we needed but instead returned just about every document in the collection.
After tinkering with the underlying issue for a bit, here's a short, self-contained example:
namespace CodePad { using System; using System.Linq; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; [BsonKnownTypes(typeof(A), typeof(B), typeof(AA))] [BsonDiscriminator(RootClass = true)] public abstract class Base { public int[] Values { get; set; } public Thing[] Things { get; set; } } public class A : Base { } public class AA : A { } public class B : Base { } public class Container { public ObjectId Id { get; set; } public Base[] Records { get; set; } } public class Thing { public int Value { get; set; } } internal class Program { static void Main(string[] args) { var coll = new MongoClient().GetDatabase("Example").GetCollection<Container>("Containers"); coll.DeleteManyAsync(Builders<Container>.Filter.Empty).Wait(); coll.InsertOneAsync(new Container{Records = new Base[]{new AA()}}).Wait(); var queryBad = coll.AsQueryable().Where(_ => _.Records.Any(r => r is A)); var queryGood1 = coll.AsQueryable().Where(_ => _.Records.Any(r => r.Values.Any(v => v > 3 && v < 56))); var queryGood2 = coll.AsQueryable().Where(_ => _.Records.Any(r => r.Things.Any(t => t.Value > 3 && t.Value < 56))); var queryGood3 = coll.AsQueryable().Where(_ => _.Records.Any(r => r.GetType() == typeof (A))); Console.WriteLine(queryBad); Console.WriteLine(queryGood1); Console.WriteLine(queryGood2); Console.WriteLine(queryGood3); Console.ReadKey(true); } } }
The above code results in the following output:
aggregate([{ "$match" : { "Records" : { "$elemMatch" : { "._t" : "A" } } } }]) aggregate([{ "$match" : { "Records.Values" : { "$elemMatch" : { "$gt" : 3, "$lt" : 56 } } } }]) aggregate([{ "$match" : { "Records.Things" : { "$elemMatch" : { "Value" : { "$gt" : 3, "$lt" : 56 } } } } }]) aggregate([{ "$match" : { "Records._t" : { "$size" : 2 }, "Records._t.0" : "Base", "Records._t.1" : "A" } }])
The first query adds a spurious "." before "_t" which basically matches to nothing. I've attempted to trigger the same bug with other fields (array of primitive BSON numbers, array of objects, another query over the discriminator using GetType()) but I couldn't get it to manifest except for the "is" keyword.
Please let me know if you need any more information.
Thanks for your time!