YMJake.ManticoreSearch.Client 1.1.0

dotnet add package YMJake.ManticoreSearch.Client --version 1.1.0
                    
NuGet\Install-Package YMJake.ManticoreSearch.Client -Version 1.1.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="YMJake.ManticoreSearch.Client" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="YMJake.ManticoreSearch.Client" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="YMJake.ManticoreSearch.Client" />
                    
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 YMJake.ManticoreSearch.Client --version 1.1.0
                    
#r "nuget: YMJake.ManticoreSearch.Client, 1.1.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 YMJake.ManticoreSearch.Client@1.1.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=YMJake.ManticoreSearch.Client&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=YMJake.ManticoreSearch.Client&version=1.1.0
                    
Install as a Cake Tool

ManticoreSearch .NET Client

Handcrafted C# SDK mirroring the official PHP client. Every endpoint, table helper, query builder, result wrapper, and admin API is handwritten—no OpenAPI artifacts remain.

Features

  • Table CRUD, bulk, DDL, PQ search/management, cluster/nodes utilities.
  • Strongly typed SearchRequestDescriptor<T> + lightweight QueryDsl clauses (match/bool/range/geo/knn/script fields/join) mirroring Elastic’s fluent API.
  • ResultSet exposes hits, took, timed_out, facets, profile metadata.
  • Connection pool with pluggable node pools (StaticManticoreNodePool, SingleManticoreNodePool, etc.), custom ILogger, IHttpTransportFactory; failing all nodes raises NoMoreNodesException with retry details.
  • Fluent options/helpers (node pools, .Authentication(), debug hooks, serializer overrides, proxy knobs) that mirror PHP config plus a public ExecuteAsync<T> escape hatch for brand-new endpoints.
  • Attribute + fluent schema mapping via TableSchemaBuilder and [ManticoreField] so tables can be created straight from your POCOs and tweaked in code.
  • Prefix/Wildcard DSLs expose analyzer/boost/case-sensitivity/max-expansion knobs in addition to the basic match.
  • Low-level escape hatch: client.LowLevel.SqlAsync / client.LowLevel.CliAsync mirror PHP’s Client::sql() / ::cli() for direct statement execution.
  • Separate request/response and source serializers with System.Text.Json context factories, so you can plug in generated JsonSerializerContext types the same way Elastic’s client does.

Quick Start

var pool = new SingleManticoreNodePool(new Uri("http://127.0.0.1:9308"));
var client = new ManticoreClient(new ManticoreClientSettings(pool));
var table = client.Table("movies");

var schema = TableSchemaBuilder.FromType<Movie>(descriptor => descriptor
    .Column(m => m.Title, "text", opts => opts.Indexed().Stored())
    .Column("created_at", "timestamp"));

await table.CreateAsync(schema, silent: true);

await table.AddDocumentAsync(new { title = "Interstellar", rating = 8.5 }, id: 1);

var typed = await table.SearchAsync<Movie>(s => s
    .Match(m => m.Title, "Interstellar")
    .Term(x => x.Genre, "sci-fi")
    .Range(x => x.Rating, gte: 8)
    .Limit(5));

foreach (var hit in new ResultSet<Movie>(typed))
{
    Console.WriteLine($"{hit.Id}: {hit.Source?.Title}");
}

// Run a vector search that reuses bool filters
var knn = await table.SearchAsync<Movie>(s => s
    .Match(m => m.Description, "space exploration")
    .WithKnnVector("embedding", new[] { 0.25f, 0.73f, -0.11f }, k: 10));

Advanced search helpers

await table.SearchAsync<Movie>(s => s
    .Match(m => m.Genre, "thriller")
    .Join(
        type: "inner",
        table: "directors",
        leftField: m => m.DirectorId,
        rightField: "id",
        leftFieldType: "int",
        joinQuery: new QueryStringQueryClause("country:US"))
        .ScriptField("score", "doc['rating'] * params.boost")
        .WithKnnDocument("embedding", documentId: 42, k: 5));

// Prefix/Wildcard sugar now exposes analyzer/boost/case sensitivity
await table.SearchAsync<Movie>(s => s
    .Prefix(m => m.Title, "star", analyzer: "keyword", boost: 1.5)
    .Wildcard("description", "space*", caseSensitive: false, maxExpansions: 50));

Flexible update-by-query

TableClient.UpdateDocumentsAsync now takes any query shape:

await table.UpdateDocumentsAsync(
    new { rating = 9.0 },
    new BoolQueryClause(
        must: new object[]
        {
            new MatchQueryClause("title", "classic"),
            new RangeQueryClause("year", lessThanOrEqual: 1980)
        }));

No need to squeeze everything through QueryFilter anymore—POCO, JsonObject, or any QueryDsl clause all work.

Direct SQL / CLI access

Need to run a raw DESCRIBE or DDL statement like the PHP client does? Use the exposed low-level transport:

var describe = await client.LowLevel.CliAsync("DESCRIBE `movies`");
Console.WriteLine(describe.Payload?["cli_output"]);

LowLevel.SqlAsync mirrors /sql (read-only) whereas LowLevel.CliAsync allows full DDL/DML via the Buddy CLI endpoint.

Calling custom endpoints

If the server ships a fresh API before the SDK catches up, craft the endpoint manually and run it through ManticoreClient.ExecuteAsync<T>:

var endpoint = new CustomEndpoint("/experimental/foo", HttpMethod.Post)
    .WithBody(new { key = "value" });

var response = await client.ExecuteAsync<MyExperimentalResponse>(endpoint);

Transport tweaks & fluent settings

var uris = new[]
{
    new Uri("https://node1.example.com:9308"),
    new Uri("https://node2.example.com:9308"),
    new Uri("https://node3.example.com:9308")
};

var pool = new StaticManticoreNodePool(uris);

var settings = new ManticoreClientSettings(
        pool,
        sourceSerializerFactory: _ => new DefaultManticoreSourceSerializer(MySourceContext.Default))
    .Authentication(new BasicAuthentication("elastic", "changeme"))
    .Proxy("http://proxy.internal:8080")
    .DisableDirectStreaming();

var client = new ManticoreClient(settings);

Need a literal single-node setup? Pass a single URI:

var pool = new SingleManticoreNodePool(new Uri("https://search.internal:9443/api"));

var settings = new ManticoreClientSettings(
        pool,
        sourceSerializerFactory: _ => new DefaultManticoreSourceSerializer(MySourceContext.Default))
    .DisableDirectStreaming()
    .Authentication(new BasicAuthentication("elastic", "Oov35Wtxj5DzpZNzYAzFb0KZ"));

var client = new ManticoreClient(settings);

MySourceContext is whatever JsonSerializerContext you generated via System.Text.Json source generators—pass delegates so we can instantiate them lazily, Elastic-style.

All of these hooks mirror the PHP client’s connection array but offer fluent, immutable .NET ergonomics.

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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. 
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
1.1.0 108 11/29/2025
1.0.0 170 11/26/2025

Initial release of the handcrafted ManticoreSearch .NET client targeting .NET 8 and .NET 10.