Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Docs/reference/content/reference/driver/admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ using (var cursor = await client.ListDatabaseAsync())

## Collections

These operations exists on the [`IMongoDatabase`]({{< apiref "T_MongoDB_Driver_IMongoDatabase" >}}) interface.
These operations exist on the [`IMongoDatabase`]({{< apiref "T_MongoDB_Driver_IMongoDatabase" >}}) interface.

### Getting a collection

Expand All @@ -88,7 +88,7 @@ var options = new CreateCollectionOptions
{
Capped = true,
MaxSize = 10000
});
};
```
```csharp
// creates a capped collection named "foo" with a maximum size of 10,000 bytes
Expand All @@ -99,6 +99,19 @@ db.CreateCollection("foo", options);
await db.CreateCollectionAsync("foo", options);
```

### Creating a clustered collection

*New in MongoDB 5.3.* [Clustered collections](https://www.mongodb.com/docs/upcoming/core/clustered-collections/) are collections created
with a clustered index. Documents in a clustered collection are ordered by the clustered index key value. To create a clustered collection:

```csharp
var options = new CreateCollectionOptions<Product>
{
ClusteredIndex = new ClusteredIndexOptions<Product>()
};
db.CreateCollection("product", options);
```

### Dropping a collection

Use the [`DropCollection`]({{< apiref "M_MongoDB_Driver_IMongoDatabase_DropCollection" >}}) or [`DropCollectionAsync`]({{< apiref "M_MongoDB_Driver_IMongoDatabase_DropCollectionAsync" >}}) methods.
Expand Down Expand Up @@ -272,4 +285,4 @@ using (var cursor = await collection.Indexes.ListAsync())
var list = await cursor.ToListAsync();
// do something with the list...
}
```
```
9 changes: 8 additions & 1 deletion src/MongoDB.Driver.Core/Core/Misc/Feature.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright 2016-present MongoDB Inc.
/* Copyright 2016-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,6 +50,7 @@ public class Feature
private static readonly Feature __changeStreamPostBatchResumeToken = new Feature("ChangeStreamPostBatchResumeToken", WireVersion.Server40);
private static readonly Feature __changeStreamPrePostImages = new Feature("ChangeStreamPrePostImages", WireVersion.Server60);
private static readonly Feature __clientSideEncryption = new Feature("ClientSideEncryption", WireVersion.Server42);
private static readonly Feature __clusteredIndexes = new Feature("ClusteredIndexes", WireVersion.Server53);
private static readonly Feature __collation = new Feature("Collation", WireVersion.Server34);
private static readonly Feature __commandMessage = new Feature("CommandMessage", WireVersion.Server36);
private static readonly Feature __commandsThatWriteAcceptWriteConcern = new Feature("CommandsThatWriteAcceptWriteConcern", WireVersion.Server34);
Expand Down Expand Up @@ -266,6 +267,12 @@ public class Feature
/// </summary>
public static Feature ClientSideEncryption => __clientSideEncryption;


/// <summary>
/// Gets the clustered indexes feature.
/// </summary>
public static Feature ClusteredIndexes => __clusteredIndexes;

/// <summary>
/// Gets the collation feature.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ CreateCollectionOperation CreateInnerCollectionOperation(string collectionName)
// fields
private bool? _autoIndexId;
private bool? _capped;
private BsonDocument _clusteredIndex;
private Collation _collation;
private readonly CollectionNamespace _collectionNamespace;
private BsonValue _comment;
Expand Down Expand Up @@ -324,6 +325,18 @@ public WriteConcern WriteConcern
set { _writeConcern = value; }
}

/// <summary>
/// Gets or sets the clustered index definition.
/// </summary>
/// <value>
/// The clustered index definition.
/// </value>
public BsonDocument ClusteredIndex
{
get => _clusteredIndex;
set => _clusteredIndex = value;
}

// methods
internal BsonDocument CreateCommand(ICoreSessionHandle session)
{
Expand All @@ -332,6 +345,7 @@ internal BsonDocument CreateCommand(ICoreSessionHandle session)
return new BsonDocument
{
{ "create", _collectionNamespace.CollectionName },
{ "clusteredIndex", _clusteredIndex, _clusteredIndex != null },
{ "capped", () => _capped.Value, _capped.HasValue },
{ "autoIndexId", () => _autoIndexId.Value, _autoIndexId.HasValue },
{ "size", () => _maxSize.Value, _maxSize.HasValue },
Expand Down
75 changes: 75 additions & 0 deletions src/MongoDB.Driver/ClusteredIndexOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using MongoDB.Bson;
using MongoDB.Bson.Serialization;

namespace MongoDB.Driver
{
/// <summary>
/// Options for creating a clustered index.
/// </summary>
public class ClusteredIndexOptions<TDocument>
{
private IndexKeysDefinition<TDocument> _key;
private string _name;
private bool _unique;

/// <summary>
/// Initializes a new instance of the <see cref="ClusteredIndexOptions{TDocument}"/> class.
/// </summary>
public ClusteredIndexOptions()
{
_key = new BsonDocument { { "_id", 1 } };
_unique = true;
}

/// <summary>
/// Gets or sets the index key, which must currently be {_id: 1}.
/// </summary>
public IndexKeysDefinition<TDocument> Key
{
get => _key;
set => _key = value;
}

/// <summary>
/// Gets or sets the index name.
/// </summary>
public string Name
{
get => _name;
set => _name = value;
}

/// <summary>
/// Gets or sets whether the index entries must be unique, which currently must be true.
/// </summary>
public bool Unique
{
get => _unique;
set => _unique = value;
}

internal BsonDocument Render(IBsonSerializer<TDocument> documentSerializer, IBsonSerializerRegistry serializerRegistry)
{
return new BsonDocument {
{ "key", _key.Render(documentSerializer, serializerRegistry) },
{ "unique", _unique },
{ "name", _name, _name != null }
};
}
}
}
10 changes: 10 additions & 0 deletions src/MongoDB.Driver/CreateCollectionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,20 @@ internal static CreateCollectionOptions<TDocument> CoercedFrom(CreateCollectionO
#endregion

// private fields
private ClusteredIndexOptions<TDocument> _clusteredIndex;
private IBsonSerializer<TDocument> _documentSerializer;
private FilterDefinition<TDocument> _validator;

// public properties
/// <summary>
/// Gets or sets the <see cref="ClusteredIndexOptions{TDocument}"/>.
/// </summary>
public ClusteredIndexOptions<TDocument> ClusteredIndex
{
get { return _clusteredIndex; }
set { _clusteredIndex = value; }
}

/// <summary>
/// Gets or sets the document serializer.
/// </summary>
Expand Down
6 changes: 0 additions & 6 deletions src/MongoDB.Driver/CreateIndexModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@
* limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver.Core.Misc;
using MongoDB.Driver.Core.Operations;

namespace MongoDB.Driver
{
Expand Down
13 changes: 6 additions & 7 deletions src/MongoDB.Driver/MongoDatabaseImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,11 @@ private Task CreateCollectionHelperAsync<TDocument>(IClientSessionHandle session

private IWriteOperation<BsonDocument> CreateCreateCollectionOperation<TDocument>(string name, CreateCollectionOptions<TDocument> options)
{
BsonDocument validator = null;
if (options.Validator != null)
{
var serializerRegistry = options.SerializerRegistry ?? BsonSerializer.SerializerRegistry;
var documentSerializer = options.DocumentSerializer ?? serializerRegistry.GetSerializer<TDocument>();
validator = options.Validator.Render(documentSerializer, serializerRegistry, _linqProvider);
}
var serializerRegistry = options.SerializerRegistry ?? BsonSerializer.SerializerRegistry;
var documentSerializer = options.DocumentSerializer ?? serializerRegistry.GetSerializer<TDocument>();

var clusteredIndex = options.ClusteredIndex?.Render(documentSerializer, serializerRegistry);
var validator = options.Validator?.Render(documentSerializer, serializerRegistry, _linqProvider);

var collectionNamespace = new CollectionNamespace(_databaseNamespace, name);

Expand All @@ -667,6 +665,7 @@ private IWriteOperation<BsonDocument> CreateCreateCollectionOperation<TDocument>
cco.AutoIndexId = options.AutoIndexId;
#pragma warning restore CS0618 // Type or member is obsolete
cco.Capped = options.Capped;
cco.ClusteredIndex = clusteredIndex;
cco.Collation = options.Collation;
cco.ExpireAfter = options.ExpireAfter;
cco.IndexOptionDefaults = options.IndexOptionDefaults?.ToBsonDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public void constructor_should_initialize_subject()
subject.AutoIndexId.Should().NotHaveValue();
#pragma warning restore
subject.Capped.Should().NotHaveValue();
subject.ClusteredIndex.Should().BeNull();
subject.Collation.Should().BeNull();
subject.EncryptedFields.Should().BeNull();
subject.IndexOptionDefaults.Should().BeNull();
Expand Down Expand Up @@ -171,6 +172,28 @@ public void CreateCommand_should_return_expected_result_when_Capped_is_set(
result.Should().Be(expectedResult);
}

[Theory]
[ParameterAttributeData]
public void CreateCommand_should_return_expected_result_when_ClusteredIndex_is_set(
[Values(null, "{ key : { _id : 1 }, unique : true }", "{ key : { _id : 1 }, unique : true, name: 'clustered index name' }")]
string clusteredIndex)
{
var subject = new CreateCollectionOperation(_collectionNamespace, _messageEncoderSettings)
{
ClusteredIndex = clusteredIndex != null ? BsonDocument.Parse(clusteredIndex) : null
};
var session = OperationTestHelper.CreateSession();

var result = subject.CreateCommand(session);

var expectedResult = new BsonDocument
{
{ "create", _collectionNamespace.CollectionName },
{ "clusteredIndex", () => BsonDocument.Parse(clusteredIndex), clusteredIndex != null }
};
result.Should().Be(expectedResult);
}

[Theory]
[ParameterAttributeData]
public void CreateCommand_should_return_expected_result_when_Collation_is_set(
Expand Down
1 change: 1 addition & 0 deletions tests/MongoDB.Driver.TestConsoleApplication/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

using System;
using System.IO;
using MongoDB.Bson;
using MongoDB.Driver.Core.Configuration;
using MongoDB.Driver.Core.Events.Diagnostics;

Expand Down
18 changes: 18 additions & 0 deletions tests/MongoDB.Driver.Tests/MongoDatabaseImplTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using MongoDB.Bson.TestHelpers.XunitExtensions;
using MongoDB.Driver.Core.Bindings;
using MongoDB.Driver.Core.Clusters;
using MongoDB.Driver.Core.Misc;
using MongoDB.Driver.Core.Operations;
using MongoDB.Driver.Core.TestHelpers.XunitExtensions;
using MongoDB.Driver.Tests;
Expand Down Expand Up @@ -381,8 +382,14 @@ public void AggregateToCollection_should_throw_when_last_stage_is_not_an_output_
[ParameterAttributeData]
public void CreateCollection_should_execute_a_CreateCollectionOperation_when_options_is_generic(
[Values(false, true)] bool usingSession,
[Values(false, true)] bool clustered,
[Values(false, true)] bool async)
{
if (clustered)
{
RequireServer.Check().Supports(Feature.ClusteredIndexes);
}

var writeConcern = new WriteConcern(1);
var subject = _subject.WithWriteConcern(writeConcern);
var session = CreateSession(usingSession);
Expand All @@ -395,6 +402,7 @@ public void CreateCollection_should_execute_a_CreateCollectionOperation_when_opt
{
AutoIndexId = false,
Capped = true,
ClusteredIndex = clustered ? new ClusteredIndexOptions<BsonDocument>() : null,
Collation = new Collation("en_US"),
IndexOptionDefaults = new IndexOptionDefaults { StorageEngine = new BsonDocument("x", 1) },
MaxDocuments = 10,
Expand Down Expand Up @@ -441,6 +449,14 @@ public void CreateCollection_should_execute_a_CreateCollectionOperation_when_opt
op.AutoIndexId.Should().Be(options.AutoIndexId);
#pragma warning restore
op.Capped.Should().Be(options.Capped);
if (clustered)
{
op.ClusteredIndex.Should().NotBeNull();
}
else
{
op.ClusteredIndex.Should().BeNull();
}
op.Collation.Should().BeSameAs(options.Collation);
op.IndexOptionDefaults.ToBsonDocument().Should().Be(options.IndexOptionDefaults.ToBsonDocument());
op.MaxDocuments.Should().Be(options.MaxDocuments);
Expand Down Expand Up @@ -515,6 +531,7 @@ public void CreateCollection_should_execute_a_CreateCollectionOperation_when_opt
op.AutoIndexId.Should().Be(options.AutoIndexId);
#pragma warning restore
op.Capped.Should().Be(options.Capped);
op.ClusteredIndex.Should().BeNull();
op.Collation.Should().BeSameAs(options.Collation);
op.IndexOptionDefaults.ToBsonDocument().Should().Be(options.IndexOptionDefaults.ToBsonDocument());
op.MaxDocuments.Should().Be(options.MaxDocuments);
Expand Down Expand Up @@ -571,6 +588,7 @@ public void CreateCollection_should_execute_a_CreateCollectionOperation_when_opt
op.AutoIndexId.Should().NotHaveValue();
#pragma warning restore
op.Capped.Should().NotHaveValue();
op.ClusteredIndex.Should().BeNull();
op.IndexOptionDefaults.Should().BeNull();
op.MaxDocuments.Should().NotHaveValue();
op.MaxSize.Should().NotHaveValue();
Expand Down
Loading