Skip to content

Commit 6e2d349

Browse files
committed
Added extension method to support old and new behaviour
1 parent 2450326 commit 6e2d349

File tree

3 files changed

+282
-44
lines changed

3 files changed

+282
-44
lines changed

Diff for: src/MongoDB.Driver/Search/OperatorSearchDefinitions.cs

+24-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ public AutocompleteSearchDefinition(
4747

4848
private protected override BsonDocument RenderArguments(
4949
RenderArgs<TDocument> args,
50-
IBsonSerializer fieldSerializer) =>
51-
new()
50+
IBsonSerializer fieldSerializer) => new()
5251
{
5352
{ "query", _query.Render() },
5453
{ "tokenOrder", _tokenOrder.ToCamelCase(), _tokenOrder != SearchAutocompleteTokenOrder.Any },
@@ -139,6 +138,11 @@ private protected override BsonDocument RenderArguments(
139138
RenderArgs<TDocument> args,
140139
IBsonSerializer fieldSerializer)
141140
{
141+
if (!_useDefaultSerialization)
142+
{
143+
return new BsonDocument("value", ToBsonValue(_value));
144+
}
145+
142146
var valueSerializer = fieldSerializer switch
143147
{
144148
null => args.SerializerRegistry.GetSerializer<TValue>(),
@@ -253,6 +257,12 @@ private protected override BsonDocument RenderArguments(
253257
RenderArgs<TDocument> args,
254258
IBsonSerializer fieldSerializer)
255259
{
260+
if (!_useDefaultSerialization)
261+
{
262+
var values = new BsonArray(_values.Select(ToBsonValue));
263+
return new BsonDocument("value", values);
264+
}
265+
256266
var valueSerializer = fieldSerializer switch
257267
{
258268
null => new ArraySerializer<TValue>(args.SerializerRegistry.GetSerializer<TValue>()),
@@ -386,6 +396,18 @@ private protected override BsonDocument RenderArguments(
386396
RenderArgs<TDocument> args,
387397
IBsonSerializer fieldSerializer)
388398
{
399+
if (!_useDefaultSerialization)
400+
{
401+
var min = ToBsonValue(_range.Min);
402+
var max = ToBsonValue(_range.Max);
403+
404+
return new BsonDocument
405+
{
406+
{ _range.IsMinInclusive ? "gte" : "gt", min, min != BsonNull.Value },
407+
{ _range.IsMaxInclusive ? "lte" : "lt", max, max != BsonNull.Value },
408+
};
409+
}
410+
389411
var valueSerializer = fieldSerializer switch
390412
{
391413
null => args.SerializerRegistry.GetSerializer<TValue>(),

Diff for: src/MongoDB.Driver/Search/SearchDefinition.cs

+58-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System;
1617
using MongoDB.Bson;
1718
using MongoDB.Bson.Serialization;
1819
using MongoDB.Driver.Core.Misc;
@@ -55,6 +56,31 @@ public static implicit operator SearchDefinition<TDocument>(string json) =>
5556
json != null ? new JsonSearchDefinition<TDocument>(json) : null;
5657
}
5758

59+
/// <summary>
60+
/// Extensions for SearchDefinition
61+
/// </summary>
62+
public static class SearchDefinitionExtensions
63+
{
64+
/// <summary>
65+
/// Sets the use of default serialization for the specified <see cref="SearchDefinition{TDocument}"/>.
66+
/// When set to true, the default serializers will be used to serialize the values of certain Atlas Search operators, such as "Equals", "In" and "Range". This will become the default behaviour in version 4.0 of the library.
67+
/// If not enabled, then a default conversion will be used.
68+
/// </summary>
69+
/// <typeparam name="TDocument">The type of the document.</typeparam>
70+
/// <param name="searchDefinition">The search definition instance.</param>
71+
/// <param name="useDefaultSerialization">Whether to use the default serialization or not.</param>
72+
/// <returns>The same <see cref="SearchDefinition{TDocument}"/> instance with default serialization enabled.</returns>
73+
/// <exception cref="InvalidOperationException">Thrown if <paramref name="searchDefinition"/> is not of a valid type/>.</exception>
74+
public static SearchDefinition<TDocument> WithDefaultSerialization<TDocument>(this SearchDefinition<TDocument> searchDefinition, bool useDefaultSerialization)
75+
{
76+
if (searchDefinition is not OperatorSearchDefinition<TDocument> op)
77+
throw new InvalidOperationException("Default serialization cannot be used with the current SearchDefinition type");
78+
79+
op.SetUseDefaultSerialization(useDefaultSerialization);
80+
return searchDefinition;
81+
}
82+
}
83+
5884
/// <summary>
5985
/// A search definition based on a BSON document.
6086
/// </summary>
@@ -134,6 +160,8 @@ private protected enum OperatorType
134160
protected readonly SearchPathDefinition<TDocument> _path;
135161
protected readonly SearchScoreDefinition<TDocument> _score;
136162

163+
protected bool _useDefaultSerialization = false;
164+
137165
private protected OperatorSearchDefinition(OperatorType operatorType)
138166
: this(operatorType, null)
139167
{
@@ -172,7 +200,36 @@ public override BsonDocument Render(RenderArgs<TDocument> args)
172200
return new(_operatorType.ToCamelCase(), renderedArgs);
173201
}
174202

175-
private protected virtual BsonDocument RenderArguments(RenderArgs<TDocument> args,
203+
private protected virtual BsonDocument RenderArguments(
204+
RenderArgs<TDocument> args,
176205
IBsonSerializer fieldSerializer) => new();
206+
207+
internal void SetUseDefaultSerialization(bool useDefaultSerialization)
208+
{
209+
_useDefaultSerialization = useDefaultSerialization;
210+
}
211+
212+
protected static BsonValue ToBsonValue<T>(T value) =>
213+
value switch
214+
{
215+
bool v => (BsonBoolean)v,
216+
sbyte v => (BsonInt32)v,
217+
byte v => (BsonInt32)v,
218+
short v => (BsonInt32)v,
219+
ushort v => (BsonInt32)v,
220+
int v => (BsonInt32)v,
221+
uint v => (BsonInt64)v,
222+
long v => (BsonInt64)v,
223+
float v => (BsonDouble)v,
224+
double v => (BsonDouble)v,
225+
decimal v => (BsonDecimal128)v,
226+
DateTime v => (BsonDateTime)v,
227+
DateTimeOffset v => (BsonDateTime)v.UtcDateTime,
228+
ObjectId v => (BsonObjectId)v,
229+
Guid v => new BsonBinaryData(v, GuidRepresentation.Standard),
230+
string v => (BsonString)v,
231+
null => BsonNull.Value,
232+
_ => throw new InvalidCastException()
233+
};
177234
}
178235
}

0 commit comments

Comments
 (0)