Building indexes in MongoDB with .NET driver 2.0 - c#

What's the new way to build indexes with the new driver 2.0?
There's no documentation whatsoever about this.
Apparently this now works with the new IndexKeysDefinitionBuilder<> interface but that's all I got so far.

You need to call and await CreateOneAsync with an IndexKeysDefinition you get by using Builders.IndexKeys:
static async Task CreateIndex()
{
var client = new MongoClient();
var database = client.GetDatabase("db");
var collection = database.GetCollection<Hamster>("collection");
await collection.Indexes.CreateOneAsync(Builders<Hamster>.IndexKeys.Ascending(_ => _.Name));
}
If you don't have a Hamster you can also create the index in a non-strongly-typed way by specifying the index's json representation:
await collection.Indexes.CreateOneAsync("{ Name: 1 }");

Related

Adding Document data in Cosmos db gives error as resource already exist

I have below unit test case where I am trying to add a list of JObjects one by one in cosmos Db, but it fails giving an error as
Resource with specified id or name already exists
while my Db actually is empty and there is no value in there. What wrong am I doing here??
[Fact]
public async Task AddDataInCosmosDbEmulator()
{
await ReadConfigAsync();
var jsonData = await ReadAllData();
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(DatabaseId, RecordingCollection);
foreach(var obj in jsonData)
{
Document doc = await client.CreateDocumentAsync(collectionUri, obj);
}
}
private async Task ReadConfigAsync()
{
client = new DocumentClient(new Uri(CosmosEndpoint), EmulatorKey,
new ConnectionPolicy {
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp
});
}
jsonData is of this format:
{{"id":"Test1","Name":"123"}},
{{"id":"Test3","Name":"12r3"}},
{{"id":"Test15","Name":"12we3"}},
{{"id":"Test12","Name":"oi123"}}
Some considerations and a suggestion. To make sure that it is something other than the entry really existing, re-write
Document doc = await client.CreateDocumentAsync(collectionUri, obj );
To
Document doc = await client.UpsertDocumentAsync(collectionUri, obj );
If this works, then it might be that your local emulator has already got the data. The thing is, that the second time you re-run the unit tests this will be a problem when you actually do an insert.
Check mocking frameworks. Unit tests should only test the code at hand, not actual persistence items and such?
How would you solve this problem on a build server? How would you pipeline this? Leave actual integration testing for integration tests. Check Unit test cosmosDb methods using Moq

Reactive consume MongoDB collection in C#

I'm trying to consume a MongoDB collection but i'm guess is there a better way to do this, better than my implementation.
These is my currently approach:
IMongoClient client = new MongoClient("mongodb://localhost");
IMongoDatabase database = client.GetDatabase("example");
while (true)
{
await Task.Delay(1000);
var collection = database.GetCollection<BsonDocument>("SyncQueue");
var documents = collection.Find(new BsonDocument()).ToList();
foreach (var doc in documents)
{
ProcessDocAndRemoveFromCollection(doc);
}
}
Would it be possible to do something like this below?
PSEUDOCODE:
IMongoClient client = new MongoClient("mongodb://localhost");
IMongoDatabase database = client.GetDatabase("example");
var subject = new Subject<BsonDocument>();
subject.Subscribe(doc => ProcessDocAndRemoveFromCollection(doc));
>>>>>>>>>>>>>>>>>>>>>
when new doc in MongoDB Collection ----> subject.OnNext(doc);
<<<<<<<<<<<<<<<<<<<<<
The key point is, I want to avoid create an infinite loop to consume the collection

mongoDB C# Driver is not returning any data

I am having a problem where C# Driver is not returning any data with either using async-await or synchronous method.
When trying to run in the command line, it works perfectly, here's the snippet:
db.Collection_StudentResults.aggregate([ { $unwind: "$modules" }, { $match: { "studentNumber": "", "modules.code": "" } } ])
and here's how I have it setup in C#:
public static async Task<BsonDocument> getSingleStudentData(string studentNumber)
{
var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("dbStudents");
var collection = db.GetCollection<BsonDocument>("Collection_StudentResults");
var aggregate = collection.Aggregate()
.Unwind("modules")
.Match(new BsonDocument { { "studentNumber", studentNumber } });
var result = await aggregate.ToListAsync();
return result.FirstOrDefault();
}
Drivers Used: v2.4.0
MongoDB Version: v3.2.10
In Collection_StudentResults, the first document contains the studentNumber and modules array, in the modules array each document has code field.
Please help!
Thanks
Sorry - my bad, bad bad bad...
I missed the db = db.getSiblingDB in my builder script - which caused the data to go into the root database.
All the best.

C# Async Function To Replace Mongo Document Does Not Work

I am currently running into an issue where I am unable to replace a Mongo document thats supposed to be updated with the following function:
public async void updateSelectedDocument(BsonDocument document)
{
var collection = mongoClient.GetDatabase("db").GetCollection<BsonDocument>("collection");
var id = document.GetElement("_id").ToString().Remove(0, 4);
var filter = Builders<BsonDocument>.Filter.Eq("_id", id);
var result = await collection.ReplaceOneAsync(filter, document, new UpdateOptions { IsUpsert = true });
}
There is no error to go off of and none of the variables are null. My connection to the mongo instance and collection works because I can perform a find and an insert. Please Let me know if you need additional information.

C# Mongo RunCommandAsync

Is it possible to run
db.Users.createIndex({"FirstName" : 1, "LastName": 1});
from the RunCommandAsync also are there examples of what can be done from the command.
As a test I tried to run this but it through an exception
var indexCommand = new BsonDocumentCommand<BsonDocument>(new BsonDocument{
{"getIndexes", "Users"}
});
var results = await database.RunCommandAsync(indexCommand);
I know I can get and create indexes from the C# drivers, however I would like to keep a script in sync between those that want to build the indexes through C# and those that want to handle it directly on the DB.
You could probably try an alternative method. Especially if you see what RunCommandAsync is expected to do with the BsonDocument. See Unit test for RunCommandAsync
Assuming you are using mongodb 3.0, can you consider the code below an alternative?
using (var results = await context.Users.Indexes.ListAsync())
{
while (await results.MoveNextAsync())
{
foreach (var current in results.Current)
{
System.Diagnostics.Debug.WriteLine(current["name"].AsString);
}
}
}

Categories

Resources