using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Read
{
///
/// A class to read MongoDb document.
///
public partial class MongoDbReader : DataAccessBase
{
///
/// The construct of the MongoDbReader class.
///
/// A instance.
public MongoDbReader(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
#region Read TKey
///
/// Asynchronously returns one document given its id.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// The Id of the document you want to get.
/// An optional partition key.
/// An optional cancellation Token.
public async virtual Task GetByIdAsync(TKey id, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
var filter = Builders.Filter.Eq("Id", id);
return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(cancellationToken);
}
///
/// Returns one document given its id.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// The Id of the document you want to get.
/// An optional partition key.
public virtual TDocument GetById(TKey id, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
var filter = Builders.Filter.Eq("Id", id);
return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault();
}
///
/// Asynchronously returns one document given filter definition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb filter option.
/// An optional partition key.
/// An optional cancellation Token.
public virtual Task GetOneAsync(FilterDefinition condition, FindOptions findOption = null,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(condition, findOption).FirstOrDefaultAsync(cancellationToken);
}
///
/// Returns one document given filter definition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb filter option.
/// An optional partition key.
public virtual TDocument GetOne(FilterDefinition condition, FindOptions findOption = null, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(condition, findOption).FirstOrDefault();
}
///
/// Asynchronously returns one document given an expression filter.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
/// An optional cancellation Token.
public async virtual Task GetOneAsync(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(cancellationToken);
}
///
/// Returns one document given an expression filter.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
public virtual TDocument GetOne(Expression> filter, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault();
}
///
/// Returns a collection cursor.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
public virtual IFindFluent GetCursor(Expression> filter, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(filter);
}
///
/// Returns true if any of the document of the collection matches the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb counting option.
/// An optional partition key.
/// An optional cancellation Token.
public virtual async Task AnyAsync(FilterDefinition condition, CountOptions countOption = null, string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
var count = await HandlePartitioned(partitionKey).CountDocumentsAsync(condition, countOption, cancellationToken);
return count > 0;
}
///
/// Returns true if any of the document of the collection matches the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb counting option.
/// An optional partition key.
public virtual bool Any(FilterDefinition condition, CountOptions countOption = null,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
var count = HandlePartitioned(partitionKey).CountDocuments(condition, countOption);
return count > 0;
}
///
/// Returns true if any of the document of the collection matches the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
/// An optional cancellation Token.
public async virtual Task AnyAsync(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
var count = await HandlePartitioned(partitionKey).CountDocumentsAsync(filter, cancellationToken: cancellationToken);
return (count > 0);
}
///
/// Returns true if any of the document of the collection matches the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
public virtual bool Any(Expression> filter, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
var count = HandlePartitioned(partitionKey).CountDocuments(filter);
return (count > 0);
}
///
/// Asynchronously returns a list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb filter option.
/// An optional partition key.
/// An optional cancellation Token.
public virtual Task> GetAllAsync(FilterDefinition condition,
FindOptions findOption = null, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(condition, findOption).ToListAsync(cancellationToken);
}
///
/// Returns a list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb filter option.
/// An optional partition key.
public virtual List GetAll(FilterDefinition condition, FindOptions findOption = null,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(condition, findOption).ToList();
}
///
/// Asynchronously returns a list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
/// An optional cancellation Token.
public async virtual Task> GetAllAsync(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await HandlePartitioned(partitionKey).Find(filter).ToListAsync(cancellationToken);
}
///
/// Returns a list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partition key.
public virtual List GetAll(Expression> filter, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(filter).ToList();
}
///
/// Asynchronously counts how many documents match the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb counting option.
/// An optional partitionKey
/// An optional cancellation Token.
public virtual Task CountAsync(FilterDefinition condition, CountOptions countOption = null,
string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).CountDocumentsAsync(condition, countOption, cancellationToken);
}
///
/// Counts how many documents match the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A mongodb filter definition.
/// A mongodb counting option.
/// An optional partitionKey
public virtual long Count(FilterDefinition condition, CountOptions countOption = null,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).CountDocuments(condition, countOption);
}
///
/// Asynchronously counts how many documents match the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partitionKey
/// An optional cancellation Token.
public async virtual Task CountAsync(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await HandlePartitioned(partitionKey).CountDocumentsAsync(filter, cancellationToken: cancellationToken);
}
///
/// Counts how many documents match the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// An optional partitionKey
public virtual long Count(Expression> filter, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return HandlePartitioned(partitionKey).Find(filter).CountDocuments();
}
#endregion
#region Min / Max
///
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// A LINQ expression filter.
/// A property selector to order by descending.
/// An optional partitionKey.
/// An optional cancellation Token.
public async virtual Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter))
.SortByDescending(maxValueSelector)
.Limit(1)
.FirstOrDefaultAsync(cancellationToken);
}
///
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// A LINQ expression filter.
/// A property selector to order by descending.
/// An optional partitionKey.
public virtual TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetCollection(partitionKey).Find(Builders.Filter.Where(filter))
.SortByDescending(maxValueSelector)
.Limit(1)
.FirstOrDefault();
}
///
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partitionKey.
/// An optional cancellation Token.
public async virtual Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter))
.SortBy(minValueSelector)
.Limit(1)
.FirstOrDefaultAsync(cancellationToken);
}
///
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partitionKey.
public virtual TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetCollection(partitionKey).Find(Builders.Filter.Where(filter))
.SortBy(minValueSelector)
.Limit(1)
.FirstOrDefault();
}
///
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// The type of the field for which you want the maximum value.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partitionKey.
/// An optional cancellation Token.
public async virtual Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetMaxMongoQuery(filter, maxValueSelector, partitionKey)
.Project(maxValueSelector)
.FirstOrDefaultAsync(cancellationToken);
}
///
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// The type of the value used to order the query.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partitionKey.
public virtual TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetMaxMongoQuery(filter, maxValueSelector, partitionKey)
.Project(maxValueSelector)
.FirstOrDefault();
}
///
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// The type of the value used to order the query.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
/// An optional cancellation Token.
public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(cancellationToken);
}
///
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
///
/// The document type.
/// The type of the primary key.
/// The type of the value used to order the query.
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault();
}
#endregion Min / Max
#region Sum TKey
///
/// Sums the values of a selected field for a given filtered collection of documents.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The field you want to sum.
/// The partition key of your document, if any.
/// An optional cancellation Token.
public virtual async Task SumByAsync(Expression> filter,
Expression> selector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetQuery(filter, partitionKey).SumAsync(selector, cancellationToken);
}
///
/// Sums the values of a selected field for a given filtered collection of documents.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The field you want to sum.
/// The partition key of your document, if any.
public virtual int SumBy(Expression> filter,
Expression> selector,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetQuery(filter, partitionKey).Sum(selector);
}
///
/// Sums the values of a selected field for a given filtered collection of documents.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The field you want to sum.
/// The partition key of your document, if any.
/// An optional cancellation Token.
public virtual async Task SumByAsync(Expression> filter,
Expression> selector,
string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await GetQuery(filter, partitionKey).SumAsync(selector, cancellationToken);
}
///
/// Sums the values of a selected field for a given filtered collection of documents.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The field you want to sum.
/// The partition key of your document, if any.
public virtual decimal SumBy(Expression> filter,
Expression> selector,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
return GetQuery(filter, partitionKey).Sum(selector);
}
#endregion Sum TKey
}
public partial class MongoDbReader
{
///
/// Groups a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// The type of the grouping criteria.
/// The type of the projected group.
/// The grouping criteria.
/// The projected group result.
/// The partition key of your document, if any.
public virtual List GroupBy(
Expression> groupingCriteria,
Expression, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
where TProjection : class, new()
{
return HandlePartitioned(partitionKey)
.Aggregate()
.Group(groupingCriteria, groupProjection)
.ToList();
}
///
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// The type of the grouping criteria.
/// The type of the projected group.
/// A LINQ expression filter.
/// The grouping criteria.
/// The projected group result.
/// The partition key of your document, if any.
public virtual List GroupBy(
Expression> filter,
Expression> selector,
Expression, TProjection>> projection,
string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
where TProjection : class, new()
{
var collection = HandlePartitioned(partitionKey);
return collection.Aggregate()
.Match(Builders.Filter.Where(filter))
.Group(selector, projection)
.ToList();
}
///
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// The type of the grouping criteria.
/// The type of the projected group.
/// A LINQ expression filter.
/// The grouping criteria.
/// The projected group result.
/// The partition key of your document, if any.
/// An optional cancellation Token.
public virtual async Task> GroupByAsync(
Expression> filter,
Expression> selector,
Expression, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
where TProjection : class, new()
{
var collection = HandlePartitioned(partitionKey);
return await collection.Aggregate()
.Match(Builders.Filter.Where(filter))
.Group(selector, projection)
.ToListAsync(cancellationToken);
}
///
/// Asynchronously returns a paginated list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The property selector.
/// Order of the sorting.
/// The number of documents you want to skip. Default value is 0.
/// The number of documents you want to take. Default value is 50.
/// An optional partition key.
/// An optional cancellation Token.
public virtual async Task> GetSortedPaginatedAsync(
Expression> filter,
Expression> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
var sorting = ascending
? Builders.Sort.Ascending(sortSelector)
: Builders.Sort.Descending(sortSelector);
return await HandlePartitioned(partitionKey)
.Find(filter)
.Sort(sorting)
.Skip(skipNumber)
.Limit(takeNumber)
.ToListAsync(cancellationToken);
}
///
/// Asynchronously returns a paginated list of the documents matching the filter condition.
///
/// The type representing a Document.
/// The type of the primary key for a Document.
/// A LINQ expression filter.
/// The sort definition.
/// The number of documents you want to skip. Default value is 0.
/// The number of documents you want to take. Default value is 50.
/// An optional partition key.
/// An optional cancellation Token.
public virtual async Task> GetSortedPaginatedAsync(
Expression> filter,
SortDefinition sortDefinition,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument
where TKey : IEquatable
{
return await HandlePartitioned(partitionKey)
.Find(filter)
.Sort(sortDefinition)
.Skip(skipNumber)
.Limit(takeNumber)
.ToListAsync(cancellationToken);
}
}
}