Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

CSHARP-4706: Support for $out to Time-series collections #1223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
adelinowona merged 8 commits into mongodb:master from adelinowona:csharp4706
Dec 7, 2023

Conversation

@adelinowona
Copy link
Contributor

@adelinowona adelinowona commented Nov 28, 2023

No description provided.

@adelinowona adelinowona requested a review from a team as a code owner November 28, 2023 00:51
@adelinowona adelinowona requested review from BorisDog, JamesKovacs and rstam and removed request for a team and rstam November 28, 2023 00:51
Copy link
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, some comments about testing.

var lastStage = pipeline.Last();
var lastStageName = lastStage.GetElement(0).Name;
if (lastStageName == "$out" && lastStage["$out"] is BsonDocument outDocument)
if (lastStageName == "$out" && lastStage["$out"] is BsonDocument outDocument&&!outDocument.Contains("timeseries"))
Copy link
Contributor

@BorisDog BorisDog Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have this tested directly or indirectly somewhere?

Copy link
Contributor Author

@adelinowona adelinowona Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tested indirectly through the Aggregate_out_to_time_series_collection_on_secondary_should_work test and the AggregateToCollection time series tests. Without this, the simplification of the out stage will just remove the timeseries options resulting in the time series tests failing.

@adelinowona adelinowona changed the title (削除) CSHARP-4706: Support for to Time-series collections (削除ここまで) (追記) CSHARP-4706: Support for $out to Time-series collections (追記ここまで) Dec 6, 2023
[Fact]
public void Out_with_time_series_options_should_add_expected_stage()
{
var client = DriverTestConfiguration.Client;
Copy link
Contributor

@BorisDog BorisDog Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we just need the collection namespace for rendering.
Maybe we can just mock the collection, and then the test would not be dependent on server?

adelinowona reacted with thumbs up emoji

var result = PipelineStageDefinitionBuilder.Out(outputCollection, timeSeriesOptions);

RenderStage(result).Document.Should().Be("{ $out: { db: 'database', coll: 'collection', timeseries: { timeField: 'time', metaField: 'symbol' } } }");
Copy link
Contributor

@BorisDog BorisDog Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about mocking collection.

adelinowona reacted with thumbs up emoji
private static readonly Feature __aggregateOut = new Feature("AggregateOut", WireVersion.Server26);
private static readonly Feature __aggregateOutTimeSeries = new Feature("AggregateOutTimeSeries", WireVersion.Server70);
private static readonly Feature __aggregateOutOnSecondary = new Feature("AggregateOutOnSecondary", WireVersion.Server50);
private static readonly Feature __aggregateOutTimeSeriesOnSecondary = new Feature("AggregateOutTimeSeriesOnSecondary", WireVersion.Server70);
Copy link
Contributor

@BorisDog BorisDog Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that we need the secondary feature.

adelinowona reacted with thumbs up emoji
IMongoCollection<TOutput> outputCollection,
TimeSeriesOptions timeSeriesOptions)
{
Ensure.IsNotNull(pipeline, nameof(pipeline));
Copy link
Contributor

@BorisDog BorisDog Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should either merge overloads (add timeSeriesOptions = null parameter) or forbid null here.
I personally would prefer having less overloads for simplicity.

Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional parameters are problematic and I think we should avoid them in our public API. We can use them internally where it makes sense, but not in our public API.

Reason 1: The optional value is inserted into the calling code at compile-time for the calling code. So if you change your default value, but don't recompile the calling code, you'll still use the same value.

Reason 2: Even more insidious is that the C# compiler doesn't enforce consistency among default values. The following is perfectly valid:

var oops1 = new EvilClass();
var oops2 = oops1 as IOops;
Console.WriteLine(oops1.GetValue());
Console.WriteLine(oops2.GetValue());
interface IOops
{
 int GetValue(int x = 42);
}
class EvilClass : IOops
{
 public int GetValue(int x = 99) => x;
}

The output is:

99
42

Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that we are already doing this elsewhere in our Fluent Aggregate API. Sigh. I guess we can use TimeSeriesOptions timeSeriesOptions = null here to reduce the number of overloads.

private static readonly Feature __aggregateLet = new Feature("AggregateLet", WireVersion.Server36);
private static readonly Feature __aggregateMerge = new Feature("AggregateMerge", WireVersion.Server42);
private static readonly Feature __aggregateOut = new Feature("AggregateOut", WireVersion.Server26);
private static readonly Feature __aggregateOutTimeSeries = new Feature("AggregateOutTimeSeries", WireVersion.Server70);
Copy link
Contributor

@BorisDog BorisDog Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order (field and property).

adelinowona reacted with thumbs up emoji
Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I don't like optional parameters (see comment below for why), we use them elsewhere. I'm fine with using an optional parameter for timeSeriesOptions and not adding more overloads. Fix that and some minor comment issues and you're good to go.

/// <typeparam name="TOutput">The type of the output documents.</typeparam>
/// <param name="pipeline">The pipeline.</param>
/// <param name="outputCollection">The output collection.</param>
/// <param name="timeSeriesOptions">The time-series options</param>
Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time-series => time series

And add period at end of the param description.

IMongoCollection<TOutput> outputCollection,
TimeSeriesOptions timeSeriesOptions)
{
Ensure.IsNotNull(pipeline, nameof(pipeline));
Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional parameters are problematic and I think we should avoid them in our public API. We can use them internally where it makes sense, but not in our public API.

Reason 1: The optional value is inserted into the calling code at compile-time for the calling code. So if you change your default value, but don't recompile the calling code, you'll still use the same value.

Reason 2: Even more insidious is that the C# compiler doesn't enforce consistency among default values. The following is perfectly valid:

var oops1 = new EvilClass();
var oops2 = oops1 as IOops;
Console.WriteLine(oops1.GetValue());
Console.WriteLine(oops2.GetValue());
interface IOops
{
 int GetValue(int x = 42);
}
class EvilClass : IOops
{
 public int GetValue(int x = 99) => x;
}

The output is:

99
42

/// </summary>
/// <typeparam name="TInput">The type of the input documents.</typeparam>
/// <param name="outputCollection">The output collection.</param>
/// <param name="timeSeriesOptions">The time series options</param>
Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Period at end of sentence.

IMongoCollection<TOutput> outputCollection,
TimeSeriesOptions timeSeriesOptions)
{
Ensure.IsNotNull(pipeline, nameof(pipeline));
Copy link
Contributor

@JamesKovacs JamesKovacs Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that we are already doing this elsewhere in our Fluent Aggregate API. Sigh. I guess we can use TimeSeriesOptions timeSeriesOptions = null here to reduce the number of overloads.

Copy link
Contributor

@BorisDog BorisDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@adelinowona adelinowona merged commit 33d356a into mongodb:master Dec 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@JamesKovacs JamesKovacs JamesKovacs requested changes

@BorisDog BorisDog BorisDog approved these changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /