Skip to content

Commit facf8a1

Browse files
committed
- Search text operator
1 parent 6a203a4 commit facf8a1

22 files changed

+1399
-95
lines changed

src/MongoDB.Driver.Core/Core/Misc/Ensure.cs

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,18 @@ public static T IsGreaterThanOrEqualTo<T>(T value, T comparand, string paramName
8383
}
8484

8585
/// <summary>
86-
/// Ensures that the value of a parameter is greater than or equal to zero.
86+
/// Ensures that the value of a parameter is greater than a comparand.
8787
/// </summary>
88+
/// <typeparam name="T">Type type of the value.</typeparam>
8889
/// <param name="value">The value of the parameter.</param>
90+
/// <param name="comparand">The comparand.</param>
8991
/// <param name="paramName">The name of the parameter.</param>
9092
/// <returns>The value of the parameter.</returns>
91-
public static int IsGreaterThanOrEqualToZero(int value, string paramName)
93+
public static T IsGreaterThan<T>(T value, T comparand, string paramName) where T : IComparable<T>
9294
{
93-
if (value < 0)
95+
if (value.CompareTo(comparand) <= 0)
9496
{
95-
var message = string.Format("Value is not greater than or equal to 0: {0}.", value);
97+
var message = $"Value is not greater than {comparand}: {value}.";
9698
throw new ArgumentOutOfRangeException(paramName, message);
9799
}
98100
return value;
@@ -104,79 +106,62 @@ public static int IsGreaterThanOrEqualToZero(int value, string paramName)
104106
/// <param name="value">The value of the parameter.</param>
105107
/// <param name="paramName">The name of the parameter.</param>
106108
/// <returns>The value of the parameter.</returns>
107-
public static long IsGreaterThanOrEqualToZero(long value, string paramName)
108-
{
109-
if (value < 0)
110-
{
111-
var message = string.Format("Value is not greater than or equal to 0: {0}.", value);
112-
throw new ArgumentOutOfRangeException(paramName, message);
113-
}
114-
return value;
115-
}
109+
public static int IsGreaterThanOrEqualToZero(int value, string paramName) =>
110+
IsGreaterThanOrEqualTo(value, 0, paramName);
116111

117112
/// <summary>
118113
/// Ensures that the value of a parameter is greater than or equal to zero.
119114
/// </summary>
120115
/// <param name="value">The value of the parameter.</param>
121116
/// <param name="paramName">The name of the parameter.</param>
122117
/// <returns>The value of the parameter.</returns>
123-
public static TimeSpan IsGreaterThanOrEqualToZero(TimeSpan value, string paramName)
124-
{
125-
if (value < TimeSpan.Zero)
126-
{
127-
var message = string.Format("Value is not greater than or equal to zero: {0}.", TimeSpanParser.ToString(value));
128-
throw new ArgumentOutOfRangeException(paramName, message);
129-
}
130-
return value;
131-
}
118+
public static long IsGreaterThanOrEqualToZero(long value, string paramName) =>
119+
IsGreaterThanOrEqualTo(value, 0, paramName);
120+
121+
/// <summary>
122+
/// Ensures that the value of a parameter is greater than or equal to zero.
123+
/// </summary>
124+
/// <param name="value">The value of the parameter.</param>
125+
/// <param name="paramName">The name of the parameter.</param>
126+
/// <returns>The value of the parameter.</returns>
127+
public static TimeSpan IsGreaterThanOrEqualToZero(TimeSpan value, string paramName) =>
128+
IsGreaterThanOrEqualTo(value, TimeSpan.Zero, paramName);
132129

133130
/// <summary>
134131
/// Ensures that the value of a parameter is greater than zero.
135132
/// </summary>
136133
/// <param name="value">The value of the parameter.</param>
137134
/// <param name="paramName">The name of the parameter.</param>
138135
/// <returns>The value of the parameter.</returns>
139-
public static int IsGreaterThanZero(int value, string paramName)
140-
{
141-
if (value <= 0)
142-
{
143-
var message = string.Format("Value is not greater than zero: {0}.", value);
144-
throw new ArgumentOutOfRangeException(paramName, message);
145-
}
146-
return value;
147-
}
136+
public static int IsGreaterThanZero(int value, string paramName) =>
137+
IsGreaterThan(value, 0, paramName);
148138

149139
/// <summary>
150140
/// Ensures that the value of a parameter is greater than zero.
151141
/// </summary>
152142
/// <param name="value">The value of the parameter.</param>
153143
/// <param name="paramName">The name of the parameter.</param>
154144
/// <returns>The value of the parameter.</returns>
155-
public static long IsGreaterThanZero(long value, string paramName)
156-
{
157-
if (value <= 0)
158-
{
159-
var message = string.Format("Value is not greater than zero: {0}.", value);
160-
throw new ArgumentOutOfRangeException(paramName, message);
161-
}
162-
return value;
163-
}
145+
public static long IsGreaterThanZero(long value, string paramName) =>
146+
IsGreaterThan(value, 0, paramName);
164147

165148
/// <summary>
166149
/// Ensures that the value of a parameter is greater than zero.
167150
/// </summary>
168151
/// <param name="value">The value of the parameter.</param>
169152
/// <param name="paramName">The name of the parameter.</param>
170153
/// <returns>The value of the parameter.</returns>
171-
public static TimeSpan IsGreaterThanZero(TimeSpan value, string paramName)
172-
{
173-
if (value <= TimeSpan.Zero)
174-
{
175-
var message = string.Format("Value is not greater than zero: {0}.", value);
176-
throw new ArgumentOutOfRangeException(paramName, message);
177-
}
178-
return value;
179-
}
154+
public static double IsGreaterThanZero(double value, string paramName) =>
155+
IsGreaterThan(value, 0, paramName);
156+
157+
/// <summary>
158+
/// Ensures that the value of a parameter is greater than zero.
159+
/// </summary>
160+
/// <param name="value">The value of the parameter.</param>
161+
/// <param name="paramName">The name of the parameter.</param>
162+
/// <returns>The value of the parameter.</returns>
163+
public static TimeSpan IsGreaterThanZero(TimeSpan value, string paramName) =>
164+
IsGreaterThan(value, TimeSpan.Zero, paramName);
180165

181166
/// <summary>
182167
/// Ensures that the value of a parameter is infinite or greater than or equal to zero.
@@ -298,6 +283,24 @@ public static T IsNull<T>(T value, string paramName) where T : class
298283
return value;
299284
}
300285

286+
/// <summary>
287+
/// Ensures that the value of a parameter is null or is between a minimum and a maximum value.
288+
/// </summary>
289+
/// <typeparam name="T">Type type of the value.</typeparam>
290+
/// <param name="value">The value of the parameter.</param>
291+
/// <param name="min">The minimum value.</param>
292+
/// <param name="max">The maximum value.</param>
293+
/// <param name="paramName">The name of the parameter.</param>
294+
/// <returns>The value of the parameter.</returns>
295+
public static T? IsNullOrBetween<T>(T? value, T min, T max, string paramName) where T : struct, IComparable<T>
296+
{
297+
if (value != null)
298+
{
299+
IsBetween(value.Value, min, max, paramName);
300+
}
301+
return value;
302+
}
303+
301304
/// <summary>
302305
/// Ensures that the value of a parameter is null or greater than or equal to zero.
303306
/// </summary>

src/MongoDB.Driver/AggregateFluent.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
* limitations under the License.
1414
*/
1515

16-
using MongoDB.Bson;
17-
using MongoDB.Bson.Serialization;
18-
using MongoDB.Driver.Core.Misc;
1916
using System.Collections.Generic;
2017
using System.Linq;
2118
using System.Threading;
2219
using System.Threading.Tasks;
20+
using MongoDB.Bson;
21+
using MongoDB.Bson.Serialization;
22+
using MongoDB.Driver.Core.Misc;
23+
using MongoDB.Driver.Search;
2324

2425
namespace MongoDB.Driver
2526
{
@@ -238,6 +239,16 @@ public override IAggregateFluent<TNewResult> ReplaceWith<TNewResult>(AggregateEx
238239
return WithPipeline(_pipeline.ReplaceWith(newRoot));
239240
}
240241

242+
public override IAggregateFluent<TResult> Search(
243+
SearchDefinition<TResult> query,
244+
HighlightOptions<TResult> highlight = null,
245+
string indexName = null,
246+
SearchCountOptions count = null,
247+
bool returnStoredSource = false)
248+
{
249+
return WithPipeline(_pipeline.Search(query, highlight, indexName, count, returnStoredSource));
250+
}
251+
241252
public override IAggregateFluent<BsonDocument> SetWindowFields<TWindowFields>(
242253
AggregateExpressionDefinition<ISetWindowFieldsPartition<TResult>, TWindowFields> output)
243254
{

src/MongoDB.Driver/AggregateFluentBase.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.Threading.Tasks;
2020
using MongoDB.Bson;
2121
using MongoDB.Bson.Serialization;
22+
using MongoDB.Driver.Search;
2223

2324
namespace MongoDB.Driver
2425
{
@@ -215,6 +216,17 @@ public virtual IAggregateFluent<TNewResult> ReplaceWith<TNewResult>(AggregateExp
215216
throw new NotImplementedException();
216217
}
217218

219+
/// <inheritdoc />
220+
public virtual IAggregateFluent<TResult> Search(
221+
SearchDefinition<TResult> query,
222+
HighlightOptions<TResult> highlight = null,
223+
string indexName = null,
224+
SearchCountOptions count = null,
225+
bool returnStoredSource = false)
226+
{
227+
throw new NotImplementedException();
228+
}
229+
218230
/// <inheritdoc />
219231
public virtual IAggregateFluent<BsonDocument> SetWindowFields<TWindowFields>(
220232
AggregateExpressionDefinition<ISetWindowFieldsPartition<TResult>, TWindowFields> output)

src/MongoDB.Driver/Builders.cs

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* limitations under the License.
1414
*/
1515

16+
using MongoDB.Driver.Search;
17+
1618
namespace MongoDB.Driver
1719
{
1820
/// <summary>
@@ -21,50 +23,29 @@ namespace MongoDB.Driver
2123
/// <typeparam name="TDocument">The type of the document.</typeparam>
2224
public static class Builders<TDocument>
2325
{
24-
private static FilterDefinitionBuilder<TDocument> __filter = new FilterDefinitionBuilder<TDocument>();
25-
private static IndexKeysDefinitionBuilder<TDocument> __index = new IndexKeysDefinitionBuilder<TDocument>();
26-
private static ProjectionDefinitionBuilder<TDocument> __projection = new ProjectionDefinitionBuilder<TDocument>();
27-
private static SortDefinitionBuilder<TDocument> __sort = new SortDefinitionBuilder<TDocument>();
28-
private static UpdateDefinitionBuilder<TDocument> __update = new UpdateDefinitionBuilder<TDocument>();
26+
/// <summary>Gets a <see cref="FilterDefinitionBuilder{TDocument}"/>.</summary>
27+
public static FilterDefinitionBuilder<TDocument> Filter { get; } = new FilterDefinitionBuilder<TDocument>();
28+
29+
/// <summary>Gets an <see cref="IndexKeysDefinitionBuilder{TDocument}"/>.</summary>
30+
public static IndexKeysDefinitionBuilder<TDocument> IndexKeys { get; } = new IndexKeysDefinitionBuilder<TDocument>();
31+
32+
/// <summary>Gets a <see cref="ProjectionDefinitionBuilder{TDocument}"/>.</summary>
33+
public static ProjectionDefinitionBuilder<TDocument> Projection { get; } = new ProjectionDefinitionBuilder<TDocument>();
2934

30-
/// <summary>
31-
/// Gets a <see cref="FilterDefinitionBuilder{TDocument}"/>.
32-
/// </summary>
33-
public static FilterDefinitionBuilder<TDocument> Filter
34-
{
35-
get { return __filter; }
36-
}
35+
/// <summary>Gets a <see cref="SortDefinitionBuilder{TDocument}"/>.</summary>
36+
public static SortDefinitionBuilder<TDocument> Sort { get; } = new SortDefinitionBuilder<TDocument>();
3737

38-
/// <summary>
39-
/// Gets an <see cref="IndexKeysDefinitionBuilder{TDocument}"/>.
40-
/// </summary>
41-
public static IndexKeysDefinitionBuilder<TDocument> IndexKeys
42-
{
43-
get { return __index; }
44-
}
38+
/// <summary>Gets an <see cref="UpdateDefinitionBuilder{TDocument}"/>.</summary>
39+
public static UpdateDefinitionBuilder<TDocument> Update { get; } = new UpdateDefinitionBuilder<TDocument>();
4540

46-
/// <summary>
47-
/// Gets a <see cref="ProjectionDefinitionBuilder{TDocument}"/>.
48-
/// </summary>
49-
public static ProjectionDefinitionBuilder<TDocument> Projection
50-
{
51-
get { return __projection; }
52-
}
41+
// Search builders
42+
/// <summary>Gets a <see cref="PathDefinition{TDocument}"/>.</summary>
43+
public static PathDefinitionBuilder<TDocument> Path { get; } = new PathDefinitionBuilder<TDocument>();
5344

54-
/// <summary>
55-
/// Gets a <see cref="SortDefinitionBuilder{TDocument}"/>.
56-
/// </summary>
57-
public static SortDefinitionBuilder<TDocument> Sort
58-
{
59-
get { return __sort; }
60-
}
45+
/// <summary>Gets a <see cref="ScoreDefinitionBuilder{TDocument}"/>.</summary>
46+
public static ScoreDefinitionBuilder<TDocument> Score { get; } = new ScoreDefinitionBuilder<TDocument>();
6147

62-
/// <summary>
63-
/// Gets an <see cref="UpdateDefinitionBuilder{TDocument}"/>.
64-
/// </summary>
65-
public static UpdateDefinitionBuilder<TDocument> Update
66-
{
67-
get { return __update; }
68-
}
48+
/// <summary>Gets a <see cref="SearchDefinitionBuilder{TDocument}"/>.</summary>
49+
public static SearchDefinitionBuilder<TDocument> Search { get; } = new SearchDefinitionBuilder<TDocument>();
6950
}
7051
}

src/MongoDB.Driver/IAggregateFluent.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.Threading.Tasks;
2020
using MongoDB.Bson;
2121
using MongoDB.Bson.Serialization;
22+
using MongoDB.Driver.Search;
2223

2324
namespace MongoDB.Driver
2425
{
@@ -353,6 +354,25 @@ IAggregateFluent<TNewResult> Lookup<TForeignDocument, TAsElement, TAs, TNewResul
353354
IAggregateFluent<BsonDocument> SetWindowFields<TWindowFields>(
354355
AggregateExpressionDefinition<ISetWindowFieldsPartition<TResult>, TWindowFields> output);
355356

357+
/// <summary>
358+
/// Appends a $search stage to the pipeline.
359+
/// </summary>
360+
/// <param name="query">The search definition.</param>
361+
/// <param name="highlight">The highlight options.</param>
362+
/// <param name="indexName">The index name.</param>
363+
/// <param name="count">The count options.</param>
364+
/// <param name="returnStoredSource">
365+
/// Flag that specifies whether to perform a full document lookup on the backend database
366+
/// or return only stored source fields directly from Atlas Search.
367+
/// </param>
368+
/// <returns>The fluent aggregate interface.</returns>
369+
IAggregateFluent<TResult> Search(
370+
SearchDefinition<TResult> query,
371+
HighlightOptions<TResult> highlight = null,
372+
string indexName = null,
373+
SearchCountOptions count = null,
374+
bool returnStoredSource = false);
375+
356376
/// <summary>
357377
/// Appends a $setWindowFields to the pipeline.
358378
/// </summary>

src/MongoDB.Driver/Linq/MongoQueryable.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using System.Threading;
2222
using System.Threading.Tasks;
2323
using MongoDB.Bson.Serialization;
24+
using MongoDB.Driver.Search;
2425

2526
namespace MongoDB.Driver.Linq
2627
{
@@ -923,6 +924,33 @@ public static IMongoQueryable<TSource> Sample<TSource>(this IMongoQueryable<TSou
923924
Expression.Constant(count)));
924925
}
925926

927+
/// <summary>
928+
/// Appends a $search stage to the LINQ pipeline
929+
/// </summary>
930+
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
931+
/// <param name="source">A sequence of values.</param>
932+
/// <param name="searchDefinition">The search definition.</param>
933+
/// <param name="highlight">The highlight options.</param>
934+
/// <param name="indexName">The index name.</param>
935+
/// <param name="count">The count options.</param>
936+
/// <param name="returnStoredSource">
937+
/// Flag that specifies whether to perform a full document lookup on the backend database
938+
/// or return only stored source fields directly from Atlas Search.
939+
/// </param>
940+
/// <returns>The fluent aggregate interface.</returns>
941+
public static IMongoQueryable<TSource> Search<TSource>(
942+
this IMongoQueryable<TSource> source,
943+
SearchDefinition<TSource> searchDefinition,
944+
HighlightOptions<TSource> highlight = null,
945+
string indexName = null,
946+
SearchCountOptions count = null,
947+
bool returnStoredSource = false)
948+
{
949+
return AppendStage(
950+
source,
951+
PipelineStageDefinitionBuilder.Search(searchDefinition, highlight, indexName, count, returnStoredSource));
952+
}
953+
926954
/// <summary>
927955
/// Projects each element of a sequence into a new form by incorporating the
928956
/// element's index.

src/MongoDB.Driver/MongoUtils.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
*/
1515

1616
using System;
17-
using System.Runtime.InteropServices;
18-
using System.Security;
1917
using System.Security.Cryptography;
2018
using System.Text;
2119
using MongoDB.Bson;
@@ -61,5 +59,8 @@ public static string ToCamelCase(string value)
6159
{
6260
return value.Length == 0 ? "" : value.Substring(0, 1).ToLower() + value.Substring(1);
6361
}
62+
63+
internal static string ToCamelCase<TEnum>(this TEnum @enum) where TEnum : Enum =>
64+
ToCamelCase(@enum.ToString());
6465
}
6566
}

0 commit comments

Comments
 (0)