Skip to content

Commit 77606ef

Browse files
committed
address pr comments
1 parent f101152 commit 77606ef

9 files changed

+283
-81
lines changed

src/MongoDB.Driver/AggregateFluent.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using MongoDB.Bson;
2121
using MongoDB.Bson.Serialization;
2222
using MongoDB.Driver.Core.Misc;
23+
using MongoDB.Driver.GeoJsonObjectModel;
2324
using MongoDB.Driver.Search;
2425

2526
namespace MongoDB.Driver
@@ -130,11 +131,25 @@ public override IAggregateFluent<TNewResult> Facet<TNewResult>(
130131
return WithPipeline(_pipeline.Facet(facets, options));
131132
}
132133

133-
public override IAggregateFluent<TResult> GeoNear<TPoint>(
134-
TPoint near,
134+
public override IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
135+
GeoJsonPoint<TCoordinates> near,
135136
GeoNearOptions<TResult> options = null)
136137
{
137-
return WithPipeline(_pipeline.GeoNear(near, options));
138+
return WithPipeline(_pipeline.GeoNear<TInput, TResult, TCoordinates, TNewResult>(near, options));
139+
}
140+
141+
public override IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
142+
TCoordinates[] near,
143+
GeoNearOptions<TResult> options = null)
144+
{
145+
return WithPipeline(_pipeline.GeoNear<TInput, TResult, TCoordinates, TNewResult>(near, options));
146+
}
147+
148+
public override IAggregateFluent<TNewResult> GeoNear<TNewResult>(
149+
BsonDocument near,
150+
GeoNearOptions<TResult> options = null)
151+
{
152+
return WithPipeline(_pipeline.GeoNear<TInput, TResult, TNewResult>(near, options));
138153
}
139154

140155
public override IAggregateFluent<TNewResult> GraphLookup<TFrom, TConnectFrom, TConnectTo, TStartWith, TAsElement, TAs, TNewResult>(

src/MongoDB.Driver/AggregateFluentBase.cs

Lines changed: 21 additions & 3 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.GeoJsonObjectModel;
2223
using MongoDB.Driver.Search;
2324

2425
namespace MongoDB.Driver
@@ -125,9 +126,26 @@ public virtual IAggregateFluent<TNewResult> Facet<TNewResult>(
125126
}
126127

127128
/// <inheritdoc />
128-
public virtual IAggregateFluent<TResult> GeoNear<TPoint>(
129-
TPoint near,
130-
GeoNearOptions<TResult> options = null) where TPoint : class
129+
public virtual IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
130+
GeoJsonPoint<TCoordinates> near,
131+
GeoNearOptions<TResult> options = null)
132+
where TCoordinates : GeoJsonCoordinates
133+
{
134+
throw new NotImplementedException();
135+
}
136+
137+
/// <inheritdoc />
138+
public virtual IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
139+
TCoordinates[] near,
140+
GeoNearOptions<TResult> options = null)
141+
{
142+
throw new NotImplementedException();
143+
}
144+
145+
/// <inheritdoc />
146+
public virtual IAggregateFluent<TNewResult> GeoNear<TNewResult>(
147+
BsonDocument near,
148+
GeoNearOptions<TResult> options = null)
131149
{
132150
throw new NotImplementedException();
133151
}

src/MongoDB.Driver/IAggregateFluent.cs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,38 @@ IAggregateFluent<TNewResult> Facet<TNewResult>(
179179
/// <summary>
180180
/// Appends a $geoNear stage to the pipeline.
181181
/// </summary>
182-
/// <typeparam name="TPoint">The type of the point. This could be a <see cref="GeoJsonPoint{TCoordinates}"/>, a 2d array or embedded document.</typeparam>
182+
/// <typeparam name="TNewResult">The type of the new result.</typeparam>
183+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
184+
/// <param name="near">The point for which to find the closest documents.</param>
185+
/// <param name="options">The options.</param>
186+
/// <returns>The fluent aggregate interface.</returns>
187+
IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
188+
GeoJsonPoint<TCoordinates> near,
189+
GeoNearOptions<TResult> options = null)
190+
where TCoordinates : GeoJsonCoordinates;
191+
192+
/// <summary>
193+
/// Appends a $geoNear stage to the pipeline.
194+
/// </summary>
195+
/// <typeparam name="TNewResult">The type of the new result.</typeparam>
196+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
197+
/// <param name="near">The point for which to find the closest documents.</param>
198+
/// <param name="options">The options.</param>
199+
/// <returns>The fluent aggregate interface.</returns>
200+
IAggregateFluent<TNewResult> GeoNear<TCoordinates, TNewResult>(
201+
TCoordinates[] near,
202+
GeoNearOptions<TResult> options = null);
203+
204+
/// <summary>
205+
/// Appends a $geoNear stage to the pipeline.
206+
/// </summary>
207+
/// <typeparam name="TNewResult">The type of the new result.</typeparam>
183208
/// <param name="near">The point for which to find the closest documents.</param>
184209
/// <param name="options">The options.</param>
185210
/// <returns>The fluent aggregate interface.</returns>
186-
IAggregateFluent<TResult> GeoNear<TPoint>(
187-
TPoint near,
188-
GeoNearOptions<TResult> options = null) where TPoint : class;
211+
IAggregateFluent<TNewResult> GeoNear<TNewResult>(
212+
BsonDocument near,
213+
GeoNearOptions<TResult> options = null);
189214

190215
/// <summary>
191216
/// Appends a $graphLookup stage to the pipeline.

src/MongoDB.Driver/IAggregateFluentExtensions.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -253,25 +253,6 @@ public static IAggregateFluent<TNewResult> Facet<TResult, TNewResult>(
253253
return aggregate.AppendStage(PipelineStageDefinitionBuilder.Facet<TResult, TNewResult>(facets));
254254
}
255255

256-
/// <summary>
257-
/// Appends a $geoNear stage to the pipeline.
258-
/// </summary>
259-
/// <typeparam name="TNewResult">The type of the new result.</typeparam>
260-
/// <typeparam name="TResult">The type of the result.</typeparam>
261-
/// <typeparam name="TPoint">The type of the point. This could be a <see cref="GeoJsonPoint{TCoordinates}"/>, a 2d array or embedded document.</typeparam>
262-
/// <param name="aggregate">The aggregate.</param>
263-
/// <param name="near">The point for which to find the closest documents.</param>
264-
/// <param name="options">The options.</param>
265-
/// <returns>The fluent aggregate interface.</returns>
266-
public static IAggregateFluent<TNewResult> GeoNear<TResult, TNewResult, TPoint>(
267-
this IAggregateFluent<TResult> aggregate,
268-
TPoint near,
269-
GeoNearOptions<TNewResult> options = null) where TPoint : class
270-
{
271-
Ensure.IsNotNull(aggregate, nameof(aggregate));
272-
return aggregate.AppendStage(PipelineStageDefinitionBuilder.GeoNear<TResult, TNewResult, TPoint>(near, options));
273-
}
274-
275256
/// <summary>
276257
/// Appends a $graphLookup stage to the pipeline.
277258
/// </summary>

src/MongoDB.Driver/PipelineDefinitionBuilder.cs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,19 +489,60 @@ public static PipelineDefinition<TInput, TInput> For<TInput>(IBsonSerializer<TIn
489489
/// Appends a $geoNear stage to the pipeline.
490490
/// </summary>
491491
/// <typeparam name="TInput">The type of the input documents.</typeparam>
492+
/// <typeparam name="TIntermediate">The type of the intermediate documents.</typeparam>
492493
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
493-
/// <typeparam name="TPoint">The type of the point. This could be a <see cref="GeoJsonPoint{TCoordinates}"/>, a 2d array or embedded document.</typeparam>
494+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
494495
/// <param name="pipeline">The pipeline.</param>
495496
/// <param name="near">The point for which to find the closest documents.</param>
496497
/// <param name="options">The options.</param>
497498
/// <returns>A new pipeline with an additional stage.</returns>
498-
public static PipelineDefinition<TInput, TOutput> GeoNear<TInput, TOutput, TPoint>(
499-
this PipelineDefinition<TInput, TOutput> pipeline,
500-
TPoint near,
501-
GeoNearOptions<TOutput> options = null) where TPoint : class
499+
public static PipelineDefinition<TInput, TOutput> GeoNear<TInput, TIntermediate, TCoordinates, TOutput>(
500+
this PipelineDefinition<TInput, TIntermediate> pipeline,
501+
GeoJsonPoint<TCoordinates> near,
502+
GeoNearOptions<TIntermediate> options = null)
503+
where TCoordinates : GeoJsonCoordinates
504+
{
505+
Ensure.IsNotNull(pipeline, nameof(pipeline));
506+
return pipeline.AppendStage(PipelineStageDefinitionBuilder.GeoNear<TIntermediate, TCoordinates, TOutput>(near, options));
507+
}
508+
509+
/// <summary>
510+
/// Appends a $geoNear stage to the pipeline.
511+
/// </summary>
512+
/// <typeparam name="TInput">The type of the input documents.</typeparam>
513+
/// <typeparam name="TIntermediate">The type of the intermediate documents.</typeparam>
514+
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
515+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
516+
/// <param name="pipeline">The pipeline.</param>
517+
/// <param name="near">The point for which to find the closest documents.</param>
518+
/// <param name="options">The options.</param>
519+
/// <returns>A new pipeline with an additional stage.</returns>
520+
public static PipelineDefinition<TInput, TOutput> GeoNear<TInput, TIntermediate, TCoordinates, TOutput>(
521+
this PipelineDefinition<TInput, TIntermediate> pipeline,
522+
TCoordinates[] near,
523+
GeoNearOptions<TIntermediate> options = null)
524+
{
525+
Ensure.IsNotNull(pipeline, nameof(pipeline));
526+
return pipeline.AppendStage(PipelineStageDefinitionBuilder.GeoNear<TIntermediate, TCoordinates, TOutput>(near, options));
527+
}
528+
529+
/// <summary>
530+
/// Appends a $geoNear stage to the pipeline.
531+
/// </summary>
532+
/// <typeparam name="TInput">The type of the input documents.</typeparam>
533+
/// <typeparam name="TIntermediate">The type of the intermediate documents.</typeparam>
534+
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
535+
/// <param name="pipeline">The pipeline.</param>
536+
/// <param name="near">The point for which to find the closest documents.</param>
537+
/// <param name="options">The options.</param>
538+
/// <returns>A new pipeline with an additional stage.</returns>
539+
public static PipelineDefinition<TInput, TOutput> GeoNear<TInput, TIntermediate, TOutput>(
540+
this PipelineDefinition<TInput, TIntermediate> pipeline,
541+
BsonDocument near,
542+
GeoNearOptions<TIntermediate> options = null)
502543
{
503544
Ensure.IsNotNull(pipeline, nameof(pipeline));
504-
return pipeline.AppendStage(PipelineStageDefinitionBuilder.GeoNear(near, options));
545+
return pipeline.AppendStage(PipelineStageDefinitionBuilder.GeoNear<TIntermediate, BsonDocument, TOutput>(near, options));
505546
}
506547

507548
/// <summary>

src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,9 @@ public static PipelineStageDefinition<TInput, TOutput> Facet<TInput, TOutput>(
614614
/// <param name="near">The point for which to find the closest documents.</param>
615615
/// <param name="options">The options.</param>
616616
/// <returns>The stage.</returns>
617-
public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TOutput, TPoint>(
617+
internal static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TPoint, TOutput>(
618618
TPoint near,
619-
GeoNearOptions<TOutput> options = null) where TPoint : class
619+
GeoNearOptions<TInput> options = null) where TPoint : class
620620
{
621621
Ensure.IsNotNull(near, nameof(near));
622622

@@ -627,7 +627,6 @@ public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TOutput,
627627
{
628628
ClientSideProjectionHelper.ThrowIfClientSideProjection(args.DocumentSerializer, operatorName);
629629
var pointSerializer = args.SerializerRegistry.GetSerializer<TPoint>();
630-
var outputRenderArgs = args.WithNewDocumentType(args.SerializerRegistry.GetSerializer<TOutput>());
631630
var geoNearOptions = new BsonDocument
632631
{
633632
{ "near", pointSerializer.ToBsonValue(near)},
@@ -636,7 +635,7 @@ public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TOutput,
636635
{ "minDistance", () => options?.MinDistance.Value, options?.MinDistance != null },
637636
{ "distanceMultiplier", () => options?.DistanceMultiplier.Value, options?.DistanceMultiplier != null },
638637
{ "key", options?.Key, options?.Key != null },
639-
{ "query", options?.Query?.Render(outputRenderArgs), options?.Query != null },
638+
{ "query", options?.Query?.Render(args), options?.Query != null },
640639
{ "includeLocs", options?.IncludeLocs, options?.IncludeLocs != null },
641640
{ "spherical", () => options?.Spherical.Value, options?.Spherical != null }
642641
};
@@ -652,15 +651,50 @@ public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TOutput,
652651
/// Creates a $geoNear stage.
653652
/// </summary>
654653
/// <typeparam name="TInput">The type of the input documents.</typeparam>
655-
/// <typeparam name="TPoint">The type of the point. This could be a <see cref="GeoJsonPoint{TCoordinates}"/>, a 2d array or embedded document.</typeparam>
654+
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
655+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
656656
/// <param name="near">The point for which to find the closest documents.</param>
657657
/// <param name="options">The options.</param>
658658
/// <returns>The stage.</returns>
659-
public static PipelineStageDefinition<TInput, TInput> GeoNear<TInput, TPoint>(
660-
TPoint near,
661-
GeoNearOptions<TInput> options = null) where TPoint : class
659+
public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TCoordinates, TOutput>(
660+
GeoJsonPoint<TCoordinates> near,
661+
GeoNearOptions<TInput> options = null)
662+
where TCoordinates : GeoJsonCoordinates
663+
{
664+
return GeoNear<TInput, GeoJsonPoint<TCoordinates>, TOutput>(near, options);
665+
}
666+
667+
/// <summary>
668+
/// Creates a $geoNear stage.
669+
/// </summary>
670+
/// <typeparam name="TInput">The type of the input documents.</typeparam>
671+
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
672+
/// <typeparam name="TCoordinates">The type of the coordinates for the point.</typeparam>
673+
/// <param name="near">The point for which to find the closest documents.</param>
674+
/// <param name="options">The options.</param>
675+
/// <returns>The stage.</returns>
676+
public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TCoordinates, TOutput>(
677+
TCoordinates[] near,
678+
GeoNearOptions<TInput> options = null)
679+
{
680+
Ensure.That(near.Length, len => len is >= 2 and <= 3, nameof(near), "Legacy coordinates array should have 2 or 3 coordinates.");
681+
return GeoNear<TInput, TCoordinates[], TOutput>(near, options);
682+
}
683+
684+
/// <summary>
685+
/// Creates a $geoNear stage.
686+
/// </summary>
687+
/// <typeparam name="TInput">The type of the input documents.</typeparam>
688+
/// <typeparam name="TOutput">The type of the output documents.</typeparam>
689+
/// <param name="near">The point for which to find the closest documents.</param>
690+
/// <param name="options">The options.</param>
691+
/// <returns>The stage.</returns>
692+
public static PipelineStageDefinition<TInput, TOutput> GeoNear<TInput, TOutput>(
693+
BsonDocument near,
694+
GeoNearOptions<TInput> options = null)
662695
{
663-
return GeoNear<TInput, TInput, TPoint>(near, options);
696+
Ensure.That(near.ElementCount, len => len is >= 2 and <= 3, nameof(near), "Legacy coordinates document should have 2 or 3 coordinates.");
697+
return GeoNear<TInput, BsonDocument, TOutput>(near, options);
664698
}
665699

666700
/// <summary>

0 commit comments

Comments
 (0)