Skip to content

Commit f7a8692

Browse files
CSHARP-3086: Hidden Indexes.
1 parent a54c4b0 commit f7a8692

File tree

14 files changed

+288
-53
lines changed

14 files changed

+288
-53
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public class Feature
6767
private static readonly Feature __geoNearCommand = new Feature("GeoNearCommand", new SemanticVersion(1, 0, 0), new SemanticVersion(4, 1, 0, ""));
6868
private static readonly Feature __groupCommand = new Feature("GroupCommand", new SemanticVersion(1, 0, 0), new SemanticVersion(4, 1, 1, ""));
6969
private static readonly Feature __hedgedReads = new Feature("HedgedReads", new SemanticVersion(4, 3, 1, ""));
70+
private static readonly Feature __hiddenIndex = new Feature("HiddenIndex", new SemanticVersion(4, 4, 0));
7071
private static readonly HintForDeleteOperationsFeature __hintForDeleteOperations = new HintForDeleteOperationsFeature("HintForDeleteOperations", new SemanticVersion(4, 3, 4));
7172
private static readonly HintForFindAndModifyFeature __hintForFindAndModifyFeature = new HintForFindAndModifyFeature("HintForFindAndModify", new SemanticVersion(4, 3, 4));
7273
private static readonly HintForUpdateAndReplaceOperationsFeature __hintForUpdateAndReplaceOperations = new HintForUpdateAndReplaceOperationsFeature("HintForUpdateAndReplaceOperations", new SemanticVersion(4, 2, 0));
@@ -321,6 +322,11 @@ public class Feature
321322
/// </summary>
322323
public static Feature HedgedReads => __hedgedReads;
323324

325+
/// <summary>
326+
/// Gets the hidden index feature.
327+
/// </summary>
328+
public static Feature HiddenIndex => __hiddenIndex;
329+
324330
/// <summary>
325331
/// Gets the hint for delete operations feature.
326332
/// </summary>

src/MongoDB.Driver.Core/Core/Operations/CreateIndexRequest.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class CreateIndexRequest
3232
private Collation _collation;
3333
private string _defaultLanguage;
3434
private TimeSpan? _expireAfter;
35+
private bool? _hidden;
3536
private string _languageOverride;
3637
private readonly BsonDocument _keys;
3738
private double? _max;
@@ -140,6 +141,15 @@ public TimeSpan? ExpireAfter
140141
set { _expireAfter = value; }
141142
}
142143

144+
/// <summary>
145+
/// Gets or sets a value indicating whether the index is hidden.
146+
/// </summary>
147+
public bool? Hidden
148+
{
149+
get { return _hidden; }
150+
set { _hidden = value; }
151+
}
152+
143153
/// <summary>
144154
/// Gets or sets the language override for text indexes.
145155
/// </summary>
@@ -346,6 +356,7 @@ internal BsonDocument CreateIndexDocument(SemanticVersion serverVersion)
346356
{ "collation", () => _collation.ToBsonDocument(), _collation != null },
347357
{ "default_language", () => _defaultLanguage, _defaultLanguage != null },
348358
{ "expireAfterSeconds", () => _expireAfter.Value.TotalSeconds, _expireAfter.HasValue },
359+
{ "hidden", () => _hidden.Value, _hidden.HasValue },
349360
{ "language_override", () => _languageOverride, _languageOverride != null },
350361
{ "max", () => _max.Value, _max.HasValue },
351362
{ "min", () => _min.Value, _min.HasValue },

src/MongoDB.Driver.Legacy/Builders/IndexOptionsBuilder.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ public static IndexOptionsBuilder SetGeoSpatialRange(double min, double max)
9090
return new IndexOptionsBuilder().SetGeoSpatialRange(min, max);
9191
}
9292

93+
/// <summary>
94+
/// Sets whether the index is hidden.
95+
/// </summary>
96+
/// <param name="value">Whether the index is hidden.</param>
97+
/// <returns>The builder (so method calls can be chained).</returns>
98+
public static IndexOptionsBuilder SetHidden(bool value)
99+
{
100+
return new IndexOptionsBuilder().SetHidden(value);
101+
}
102+
93103
/// <summary>
94104
/// Sets the name of the index.
95105
/// </summary>
@@ -277,6 +287,17 @@ public IndexOptionsBuilder SetGeoSpatialRange(double min, double max)
277287
return this;
278288
}
279289

290+
/// <summary>
291+
/// Sets whether the index is hidden.
292+
/// </summary>
293+
/// <param name="value">Whether the index is hidden.</param>
294+
/// <returns>The builder (so method calls can be chained).</returns>
295+
public IndexOptionsBuilder SetHidden(bool value)
296+
{
297+
_document["hidden"] = value;
298+
return this;
299+
}
300+
280301
/// <summary>
281302
/// Sets the name of the index.
282303
/// </summary>
@@ -481,6 +502,16 @@ public static IndexOptionsBuilder<TDocument> SetDropDups(bool value)
481502
return new IndexOptionsBuilder<TDocument>().SetDropDups(value);
482503
}
483504

505+
/// <summary>
506+
/// Sets whether the index is hidden.
507+
/// </summary>
508+
/// <param name="value">Whether the index is hidden.</param>
509+
/// <returns>The builder (so method calls can be chained).</returns>
510+
public static IndexOptionsBuilder<TDocument> SetHidden(bool value)
511+
{
512+
return new IndexOptionsBuilder<TDocument>().SetHidden(value);
513+
}
514+
484515
/// <summary>
485516
/// Sets the geospatial range.
486517
/// </summary>
@@ -685,6 +716,17 @@ public IndexOptionsBuilder<TDocument> SetGeoSpatialRange(double min, double max)
685716
return this;
686717
}
687718

719+
/// <summary>
720+
/// Sets whether the index is hidden.
721+
/// </summary>
722+
/// <param name="value">Whether the index is hidden.</param>
723+
/// <returns>The builder (so method calls can be chained).</returns>
724+
public IndexOptionsBuilder<TDocument> SetHidden(bool value)
725+
{
726+
_indexOptionsBuilder.SetHidden(value);
727+
return this;
728+
}
729+
688730
/// <summary>
689731
/// Sets the name of the index.
690732
/// </summary>

src/MongoDB.Driver.Legacy/GetIndexesResult.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ public bool IsBackground
140140
}
141141
}
142142

143+
/// <summary>
144+
/// Gets a value indicating whether the index is hidden.
145+
/// </summary>
146+
public bool IsHidden
147+
{
148+
get
149+
{
150+
if (_document.TryGetValue("hidden", out var value))
151+
{
152+
return value.ToBoolean();
153+
}
154+
else
155+
{
156+
return false;
157+
}
158+
}
159+
}
160+
143161
/// <summary>
144162
/// Gets a value indicating whether the index is sparse.
145163
/// </summary>

src/MongoDB.Driver/CreateIndexOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class CreateIndexOptions
3030
private Collation _collation;
3131
private string _defaultLanguage;
3232
private TimeSpan? _expireAfter;
33+
private bool? _hidden;
3334
private string _languageOverride;
3435
private double? _max;
3536
private double? _min;
@@ -98,6 +99,15 @@ public TimeSpan? ExpireAfter
9899
set { _expireAfter = value; }
99100
}
100101

102+
/// <summary>
103+
/// Gets or sets a value indicating whether the index is hidden.
104+
/// </summary>
105+
public bool? Hidden
106+
{
107+
get { return _hidden; }
108+
set { _hidden = value; }
109+
}
110+
101111
/// <summary>
102112
/// Gets or sets the language override.
103113
/// </summary>
@@ -225,6 +235,7 @@ internal static CreateIndexOptions<TDocument> CoercedFrom(CreateIndexOptions opt
225235
Collation = options.Collation,
226236
DefaultLanguage = options.DefaultLanguage,
227237
ExpireAfter = options.ExpireAfter,
238+
Hidden = options.Hidden,
228239
LanguageOverride = options.LanguageOverride,
229240
Max = options.Max,
230241
Min = options.Min,

src/MongoDB.Driver/MongoCollectionImpl.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,7 @@ private IEnumerable<CreateIndexRequest> CreateCreateIndexRequests(IEnumerable<Cr
15661566
Collation = options.Collation,
15671567
DefaultLanguage = options.DefaultLanguage,
15681568
ExpireAfter = options.ExpireAfter,
1569+
Hidden = options.Hidden,
15691570
LanguageOverride = options.LanguageOverride,
15701571
Max = options.Max,
15711572
Min = options.Min,

tests/MongoDB.Driver.Core.Tests/Core/Operations/CreateIndexRequestTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public void constructor_should_initialize_subject()
116116
subject.Collation.Should().BeNull();
117117
subject.DefaultLanguage.Should().BeNull();
118118
subject.ExpireAfter.Should().NotHaveValue();
119+
subject.Hidden.Should().NotHaveValue();
119120
subject.LanguageOverride.Should().BeNull();
120121
subject.Max.Should().NotHaveValue();
121122
subject.Min.Should().NotHaveValue();
@@ -323,6 +324,27 @@ public void CreateIndexDocument_should_return_expected_result_when_ExpireAfter_i
323324
result.Should().Be(expectedResult);
324325
}
325326

327+
[Theory]
328+
[ParameterAttributeData]
329+
public void CreateIndexDocument_should_return_expected_result_when_Hidden_is_set([Values(null, false, true)] bool? hidden)
330+
{
331+
var keys = new BsonDocument("x", 1);
332+
var subject = new CreateIndexRequest(keys)
333+
{
334+
Hidden = hidden
335+
};
336+
337+
var result = subject.CreateIndexDocument(null);
338+
339+
var expectedResult = new BsonDocument
340+
{
341+
{ "key", keys },
342+
{ "name", "x_1" },
343+
{ "hidden", () => hidden.Value, hidden.HasValue }
344+
};
345+
result.Should().Be(expectedResult);
346+
}
347+
326348
[Theory]
327349
[ParameterAttributeData]
328350
public void CreateIndexDocument_should_return_expected_result_when_LanguageOverride_is_set(
@@ -689,6 +711,19 @@ public void ExpireAfter_get_and_set_should_work(
689711
result.Should().Be(value);
690712
}
691713

714+
[Theory]
715+
[ParameterAttributeData]
716+
public void Hidden_get_and_set_should_work(
717+
[Values(null, false, true)] bool? value)
718+
{
719+
var subject = new CreateIndexRequest(new BsonDocument("x", 1));
720+
721+
subject.Hidden = value;
722+
var result = subject.Hidden;
723+
724+
result.Should().Be(value);
725+
}
726+
692727
[Theory]
693728
[ParameterAttributeData]
694729
public void LanguageOverride_get_and_set_should_work(

tests/MongoDB.Driver.Core.Tests/Core/Operations/CreateIndexesOperationTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,33 @@ public void Execute_should_work_when_expireAfter_has_value(
254254
index["expireAfterSeconds"].ToDouble().Should().Be(expireAfter.TotalSeconds);
255255
}
256256

257+
[SkippableTheory]
258+
[ParameterAttributeData]
259+
public void Execute_should_work_when_hidden_has_value(
260+
[Values(null, false, true)] bool? hidden,
261+
[Values(false, true)] bool async)
262+
{
263+
RequireServer.Check().Supports(Feature.HiddenIndex);
264+
DropCollection();
265+
var requests = new[] { new CreateIndexRequest(new BsonDocument("x", 1)) { Hidden = hidden} };
266+
var subject = new CreateIndexesOperation(_collectionNamespace, requests, _messageEncoderSettings);
267+
268+
var result = ExecuteOperation(subject, async);
269+
270+
result["ok"].ToBoolean().Should().BeTrue();
271+
272+
var indexes = ListIndexes();
273+
var index = indexes.Single(i => i["name"].AsString == "x_1");
274+
if (hidden.GetValueOrDefault())
275+
{
276+
index["hidden"].AsBoolean.Should().BeTrue();
277+
}
278+
else
279+
{
280+
index.Contains("hidden").Should().BeFalse();
281+
}
282+
}
283+
257284
[SkippableTheory]
258285
[ParameterAttributeData]
259286
public void Execute_should_work_when_unique_is_true(

tests/MongoDB.Driver.Core.Tests/Core/Operations/CreateIndexesUsingCommandOperationTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,31 @@ public void Execute_should_work_when_expireAfter_has_value(
431431
index["expireAfterSeconds"].ToDouble().Should().Be(expireAfter.TotalSeconds);
432432
}
433433

434+
[SkippableTheory]
435+
[ParameterAttributeData]
436+
public void Execute_should_work_when_hidden_has_value(
437+
[Values(null, false, true)] bool? hidden,
438+
[Values(false, true)] bool async)
439+
{
440+
RequireServer.Check().Supports(Feature.HiddenIndex);
441+
DropCollection();
442+
var requests = new[] { new CreateIndexRequest(new BsonDocument("x", 1)) { Hidden = hidden } };
443+
var subject = new CreateIndexesUsingCommandOperation(_collectionNamespace, requests, _messageEncoderSettings);
444+
445+
ExecuteOperation(subject, async);
446+
447+
var indexes = ListIndexes();
448+
var index = indexes.Single(i => i["name"].AsString == "x_1");
449+
if (hidden.GetValueOrDefault())
450+
{
451+
index["hidden"].AsBoolean.Should().BeTrue();
452+
}
453+
else
454+
{
455+
index.Contains("hidden").Should().BeFalse();
456+
}
457+
}
458+
434459
[SkippableTheory]
435460
[ParameterAttributeData]
436461
public void Execute_should_work_when_unique_is_true(

tests/MongoDB.Driver.Legacy.Tests/Builders/IndexOptionsBuilderTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ public void TestGeoSpatialRange()
5555
Assert.Equal(expected, options.ToJson());
5656
}
5757

58+
[Fact]
59+
public void TestHidden()
60+
{
61+
var options = IndexOptions.SetHidden(true);
62+
options.ToBsonDocument().Should().Be("{ hidden : true }");
63+
}
64+
5865
[Fact]
5966
public void TestName()
6067
{

0 commit comments

Comments
 (0)