SeekKit.MongoDB 2.2.0

dotnet add package SeekKit.MongoDB --version 2.2.0
                    
NuGet\Install-Package SeekKit.MongoDB -Version 2.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SeekKit.MongoDB" Version="2.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SeekKit.MongoDB" Version="2.2.0" />
                    
Directory.Packages.props
<PackageReference Include="SeekKit.MongoDB" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SeekKit.MongoDB --version 2.2.0
                    
#r "nuget: SeekKit.MongoDB, 2.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SeekKit.MongoDB@2.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SeekKit.MongoDB&version=2.2.0
                    
Install as a Cake Addin
#tool nuget:?package=SeekKit.MongoDB&version=2.2.0
                    
Install as a Cake Tool

SeekKit.MongoDB

High-performance cursor (keyset) pagination for MongoDB. Constant-time page navigation on any collection size, with opaque bidirectional tokens — built on the official MongoDB .NET driver.

Shares its token format and result contracts (SeekResult<T>, SeekRequest) with SeekKit.EntityFramework, so SQL and MongoDB endpoints can expose one identical pagination API.

Quick start

// 1. Register (Program.cs)
builder.Services.AddSeekKitMongo(options =>
{
    options.DefaultPageSize = 20;
    options.MaxPageSize     = 100;
});

// 2. Paginate a collection
public class ProductService(ISeekMongoService seek, IMongoCollection<Product> products)
{
    public async Task<SeekResult<Product>> GetPageAsync(SeekRequest request)
        => await seek.SeekAsync(
            products.AsQueryable().Where(p => p.IsActive),
            request,
            b => b.OrderByDescending(p => p.CreatedAt)
                  .OrderBy(p => p.Id));   // unique column last (e.g. _id)
}

The response carries opaque nextToken / previousToken values — the client passes them back to navigate. The keyset predicate is translated into an indexable $or filter; create a compound index matching your sort (e.g. { CreatedAt: -1, _id: 1 }) and page 1,000,000 costs the same as page 1.

Entry points

Every query model of the driver is supported — same (source, request, configure) call, same SeekResult<T>:

Source Use when
IMongoCollection<T> Paginate a whole collection
IQueryable<T> LINQ query — AsQueryable().Where(...), .Union(...) across collections
IAggregateFluent<T> Aggregation pipeline — $unionWith, $lookup, custom stages
IFindFluent<T, T> BSON FilterDefinition — text/geo/$expr filters LINQ can't express
// aggregation pipeline
await seek.SeekAsync(live.Aggregate().UnionWith(archive), request,
    b => b.OrderByDescending(p => p.CreatedAt).OrderBy(p => p.Id));

// find with a BSON filter
await seek.SeekAsync(products.Find(Builders<Product>.Filter.Text("wireless")), request,
    b => b.OrderByDescending(p => p.Score).OrderBy(p => p.Id));

seek.CreateBuilder(...) returns an origin-specific builder — ISeekMongoQueryableBuilder<T> / ISeekMongoAggregateBuilder<T> / ISeekMongoFindBuilder<T> — but all three share WithRequest/OrderBy/ OrderByDescending/ToSeekResultAsync, so ordinary usage doesn't need to care which one you got.

Push-down projection

Every builder origin has a Select<TResult> that defers a join/projection to run after the keyset filter, sort, and limit — one transformer shape per origin:

// Queryable/collection
await seek.CreateBuilder(products)
    .OrderByDescending(p => p.CreatedAt).OrderBy(p => p.Id)
    .WithRequest(request)
    .Select(q => q.Select(p => new ProductDto { Id = p.Id, CreatedAt = p.CreatedAt }))
    .ToSeekResultAsync();

// Aggregation pipeline — append raw BsonDocument $lookup/$project stages
// (the LINQ3 provider can't translate a typed Lookup<>() here)
await seek.CreateBuilder(products.Aggregate())
    .OrderByDescending(p => p.CreatedAt).OrderBy(p => p.Id)
    .WithRequest(request)
    .Select(pipeline => pipeline
        .AppendStage<BsonDocument>(lookupStage)
        .AppendStage<ProductWithCategory>(projectStage))
    .ToSeekResultAsync();

TResult must expose public properties with the same names/types as the sort columns so SeekKit can read cursor values from the projected shape. WithStrategy exists only on the queryable builder — Mongo has no aggregate/find-specific ISeekFilterStrategy to switch to.

Features

  • Constant-time paging — no skip, purely index-driven
  • Bidirectional navigation with opaque tokens
  • Paginate collections, LINQ queryables, aggregation pipelines, and find queries
  • Push-down projection via Select<TResult> on every builder origin
  • ObjectId supported out of the box as sort/tie-breaker column
  • Multi-column sorting with mixed directions
  • Optional HMAC-SHA256 token signing (config.UseHmacSigning(key))
  • DTO projection via result.Map(...) preserving all metadata (in-memory, post-fetch)
  • Targets .NET 8 / 9 / 10 and .NET Standard 2.1

Licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.2.0 36 7/25/2026
2.1.0 46 7/25/2026
2.0.0 95 7/14/2026