Skip to content

Instantly share code, notes, and snippets.

@steamonimo
Last active April 28, 2021 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steamonimo/08ae063efc1900e77db8a0fdd5d46ef0 to your computer and use it in GitHub Desktop.
Save steamonimo/08ae063efc1900e77db8a0fdd5d46ef0 to your computer and use it in GitHub Desktop.
MongoDB: c#

MongoDB: c# development

Async linq needs these imports

using MongoDB.Driver;
using MongoDB.Driver.Linq;

Async query with join returning object from collection

var query = (from a in collectionA.AsQueryable()
             join b in collectionB on a.Id equals b.whateverId
             where a.AttributeId == 10
             select a);

var list = await query.ToListAsync();

Note:

  • MongoDB can not filter on joined collectionB
  • MongoDB can not use multiple attributes to join collections
  • MongoDB can only filter on collectionA with where clause

Async query with join returning new object from multiple collections

var query = (from a in collectionA.AsQueryable()
             join b in collectionB on a.Id equals b.whateverId
             where a.AttributeId == 10
             select new ObjectClass
             {
               Attribute1 = a.Attribute1
               Attribute2 = b.Attribute2
             });

var list = await query.ToListAsync();

Note:

  • you have to define class ObjectClass
  • list will be of type list

Find with filter

var filter = collectionA.Find(o => o.Id == "x").Filter;

Filter can be used to find

try
{
  var o = await collectionA.Find(filter).Limit(1).Single<CollectionAClass>();
}
catch
{
  // not found
}

Filter can be used to delete

await collectionA.DeleteManyAsync(filter);

Filter can be used to update

var update = Builders<CollectionAClass>.Update
                .Set(o => o.Attribute1, Value1)
                .Set(o => o.Attribute2, Value2);

// one
await collectionA.UpdateOneAsync(filter, update);

// or many
await collectionA.UpdateManyAsync(filter, update);

Filter can be used to increment value in one atomic operation

var update = Builders<CollectionAClass>.Update.Inc(o => o.Attribute1, 1);

await collectionA.UpdateOneAsync(filter, update);

Filter can be used to remove one specific element from array of strings

var update = Builders<CollectionAClass>.Update.PullFilter(
                o => o.Array,
                e => e == "STRINGTOPULL");
                
await collectionA.UpdateOneAsync(filter, update);

Filter can be used to upsert (insert or update)

var update = Builders<CollectionAClass>.Update
                .Set(o => o.Attribute1, Value1)
                .Set(o => o.Attribute2, Value2);
                
await collectionA.UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true });

Filter can be used with cursor to enumerate results

using (IAsyncCursor<CollectionAClass> cursorA = await collectionA.Find(filter).ToCursorAsync())
{
    while (await cursorA.MoveNextAsync())
    {
        foreach (var objA in cursorA.Current)
        {
        }
    }
}

Aggregate with filter

BsonArray subsetBson = new BsonArray();
subsetBson.Add("A");
subsetBson.Add("B");

BsonArray relationOfSetsBson = new BsonArray();
relationOfSetsBson.Add(BsonElement{subSet, "$set"});

var pipelineAggregate = PipelineDefinition<Consumer, BsonDocument>.Create(
  new BsonDocument { { "$match", new BsonDocument { { "_id", Id } } } },
  new BsonDocument { { "$project", new BsonDocument { { "tags", 1 }, { "IsSubset", new BsonDocument { { "$setIsSubset", subsetBson } } } } } },
  new BsonDocument { { "$match", new BsonDocument { { "IsSubset", true } } } });

var aggregate = consumerCollection.Aggregate(pipelineAggregate);
var results = await aggregate.ToListAsync();

Note:

  • My ObjectA in the CollectionA has an array of strings called "set"
  • the current content of "set" is ["A", "B", "C"]

Transactions

using (var session = await mongoClient.StartSessionAsync())
{
  session.StartTransaction();

  try
  {
    ...
    await session.CommitTransactionAsync();
  }
  catch
  {
    await session.AbortTransactionAsync();
  }
}

Note:

  • Transactions are only supported on replication sets
  • For development you can create a replication set consisting of one node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment