diff --git a/src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs b/src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs index 110cbf10f3f..7faaca43bfd 100644 --- a/src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs +++ b/src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs @@ -145,7 +145,9 @@ private static BsonValue ToBsonValue(TField value) => DateTime v => (BsonDateTime)v, DateTimeOffset v => (BsonDateTime)v.UtcDateTime, ObjectId v => (BsonObjectId)v, + Guid v => new BsonBinaryData(v, GuidRepresentation.Standard), string v => (BsonString)v, + null => BsonNull.Value, _ => throw new InvalidCastException() }; } @@ -259,6 +261,7 @@ private static BsonValue ToBsonValue(TField value) => DateTimeOffset v => (BsonDateTime)v.UtcDateTime, string v => (BsonString)v, ObjectId v => (BsonObjectId)v, + Guid v => new BsonBinaryData(v, GuidRepresentation.Standard), _ => throw new InvalidCastException() }; } diff --git a/src/MongoDB.Driver/Search/SearchDefinitionBuilder.cs b/src/MongoDB.Driver/Search/SearchDefinitionBuilder.cs index b32f8544560..aab035707e9 100644 --- a/src/MongoDB.Driver/Search/SearchDefinitionBuilder.cs +++ b/src/MongoDB.Driver/Search/SearchDefinitionBuilder.cs @@ -111,7 +111,7 @@ public SearchDefinition EmbeddedDocument( /// /// Creates a search definition that queries for documents where an indexed field is equal /// to the specified value. - /// Supported value types are boolean, numeric, ObjectId, date and string. + /// Supported value types are null, boolean, numeric, ObjectId, Guid, date and string. /// /// The type of the field. /// The indexed field to search. @@ -127,7 +127,7 @@ public SearchDefinition Equals( /// /// Creates a search definition that queries for documents where an indexed field is equal /// to the specified value. - /// Supported value types are boolean, numeric, ObjectId, date and string. + /// Supported value types are null, boolean, numeric, ObjectId, Guid, date and string. /// /// The type of the field. /// The indexed field to search. @@ -316,7 +316,7 @@ public SearchDefinition GeoWithin( /// /// Creates a search definition that queries for documents where the value of the field equals to any of specified values. /// - /// The type of the field. Valid types are: boolean, ObjectId, number, date, string. + /// The type of the field. Valid types are: boolean, ObjectId, Guid, number, date, string. /// The indexed field or fields to search. /// Values to compare the field with. /// The score modifier. @@ -330,7 +330,7 @@ public SearchDefinition In( /// /// Creates a search definition that queries for documents where the value of the field equals to any of specified values. /// - /// The type of the field. Valid types are: boolean, ObjectId, number, date, string. + /// The type of the field. Valid types are: boolean, ObjectId, Guid, number, date, string. /// The indexed field or fields to search. /// Values to compare the field with. /// The score modifier. diff --git a/tests/MongoDB.Driver.Tests/Search/AtlasSearchTests.cs b/tests/MongoDB.Driver.Tests/Search/AtlasSearchTests.cs index 24dd191046d..e01175f1ae9 100644 --- a/tests/MongoDB.Driver.Tests/Search/AtlasSearchTests.cs +++ b/tests/MongoDB.Driver.Tests/Search/AtlasSearchTests.cs @@ -131,6 +131,28 @@ public void EmbeddedDocument() } } + [Fact] + public void EqualsGuid() + { + var testGuid = Guid.Parse("b52af144-bc97-454f-a578-418a64fa95bf"); + + var result = GetExtraTestsCollection().Aggregate() + .Search(Builders.Search.Equals(c => c.TestGuid, testGuid)) + .Single(); + + result.Name.Should().Be("test6"); + } + + [Fact] + public void EqualsNull() + { + var result = GetExtraTestsCollection().Aggregate() + .Search(Builders.Search.Equals(c => c.TestString, null)) + .Single(); + + result.Name.Should().Be("testNull"); + } + [Fact] public void EqualsArrayField() { @@ -266,6 +288,23 @@ public void In() results[1].Runtime.Should().Be(31); } + [Fact] + public void InGuid() + { + var testGuids = new[] + { + Guid.Parse("b52af144-bc97-454f-a578-418a64fa95bf"), Guid.Parse("84da5d44-bc97-454f-a578-418a64fa937a") + }; + + var result = GetExtraTestsCollection().Aggregate() + .Search(Builders.Search.In(c => c.TestGuid, testGuids)) + .Limit(10) + .ToList(); + + result.Should().HaveCount(2); + result.Select(s => s.Name).Should().BeEquivalentTo(["test6", "test7"]); + } + [Fact] public void MoreLikeThis() { @@ -767,6 +806,10 @@ private IMongoCollection GetEmbeddedMoviesCollection() => _mongoC .GetDatabase("sample_mflix") .GetCollection("embedded_movies"); + private IMongoCollection GetExtraTestsCollection() => _mongoClient + .GetDatabase("csharpExtraTests") + .GetCollection("testClasses"); + [BsonIgnoreExtraElements] public class Comment { @@ -881,5 +924,22 @@ public class EmbeddedMovie [BsonElement("score")] public double Score { get; set; } } + + [BsonIgnoreExtraElements] + private class TestClass + { + [BsonId] + public ObjectId Id { get; set; } + + [BsonElement("name")] + public string Name { get; set; } + + [BsonElement("testString")] + public string TestString { get; set; } + + [BsonGuidRepresentation(GuidRepresentation.Standard)] + [BsonElement("testGuid")] + public Guid TestGuid { get; set; } + } } } diff --git a/tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs b/tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs index 9f3ac2c2613..ba8c9f0c081 100644 --- a/tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs +++ b/tests/MongoDB.Driver.Tests/Search/SearchDefinitionBuilderTests.cs @@ -312,6 +312,8 @@ public void Equals_should_render_supported_type( new object[] { DateTime.MinValue, "ISODate(\"0001-01-01T00:00:00Z\")", Exp(p => p.Birthday), "dob" }, new object[] { DateTimeOffset.MaxValue, "ISODate(\"9999-12-31T23:59:59.999Z\")", Exp(p => p.DateTimeOffset), nameof(Person.DateTimeOffset) }, new object[] { ObjectId.Empty, "{ $oid: '000000000000000000000000' }", Exp(p => p.Id), "_id" }, + new object[] { Guid.Empty, """{ "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAA==", "subType" : "04" } }""", Exp(p => p.Guid), nameof(Person.Guid) }, + new object[] { null, "null", Exp(p => p.Name), nameof(Person.Name) }, new object[] { "Jim", "\"Jim\"", Exp(p => p.FirstName), "fn" } }; @@ -553,6 +555,7 @@ public void In_typed( new object[] { new[] { DateTime.MinValue, DateTime.MaxValue }, new[] { "ISODate(\"0001-01-01T00:00:00Z\")", "ISODate(\"9999-12-31T23:59:59.999Z\")" }, Exp(p => p.Birthday), "dob" }, new object[] { new[] { DateTimeOffset.MinValue, DateTimeOffset.MaxValue }, new[] { "ISODate(\"0001-01-01T00:00:00Z\")", "ISODate(\"9999-12-31T23:59:59.999Z\")" }, Exp(p => p.DateTimeOffset), nameof(Person.DateTimeOffset)}, new object[] { new[] { ObjectId.Empty, ObjectId.Parse("4d0ce088e447ad08b4721a37") }, new[] { "{ $oid: '000000000000000000000000' }", "{ $oid: '4d0ce088e447ad08b4721a37' }" }, Exp(p => p.Id), "_id" }, + new object[] { new[] { Guid.Empty, Guid.Parse("b52af144-bc97-454f-a578-418a64fa95bf") }, new[] { """{ "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAA==", "subType" : "04" } }""", """{ "$binary" : { "base64" : "tSrxRLyXRU+leEGKZPqVvw==", "subType" : "04" } }""" }, Exp(p => p.Guid), nameof(Person.Guid) }, new object[] { new object[] { (byte)1, (short)2, (int)3 }, new[] { "1", "2", "3" }, Exp(p => p.Object), nameof(Person.Object) } }; @@ -1240,7 +1243,7 @@ public class Person : SimplePerson public float Float { get; set; } public double Double { get; set; } public decimal Decimal { get; set; } - + public Guid Guid { get; set; } public DateTimeOffset DateTimeOffset { get; set; } public TimeSpan TimeSpan { get; set; } @@ -1263,6 +1266,8 @@ public class Person : SimplePerson public string[] Hobbies { get; set; } public object Object { get; set; } + + public string Name { get; set; } } public class Family