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
<PackageReference Include="YMJake.ManticoreSearch.Client" Version="1.1.0" />
<PackageVersion Include="YMJake.ManticoreSearch.Client" Version="1.1.0" />
<PackageReference Include="YMJake.ManticoreSearch.Client" />
paket add YMJake.ManticoreSearch.Client --version 1.1.0
#r "nuget: YMJake.ManticoreSearch.Client, 1.1.0"
#:package YMJake.ManticoreSearch.Client@1.1.0
#addin nuget:?package=YMJake.ManticoreSearch.Client&version=1.1.0
#tool nuget:?package=YMJake.ManticoreSearch.Client&version=1.1.0
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>+ lightweightQueryDslclauses (match/bool/range/geo/knn/script fields/join) mirroring Elastic’s fluent API. ResultSetexposes hits, took, timed_out, facets, profile metadata.- Connection pool with pluggable node pools (
StaticManticoreNodePool,SingleManticoreNodePool, etc.), customILogger,IHttpTransportFactory; failing all nodes raisesNoMoreNodesExceptionwith retry details. - Fluent options/helpers (node pools,
.Authentication(), debug hooks, serializer overrides, proxy knobs) that mirror PHP config plus a publicExecuteAsync<T>escape hatch for brand-new endpoints. - Attribute + fluent schema mapping via
TableSchemaBuilderand[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.CliAsyncmirror PHP’sClient::sql()/::cli()for direct statement execution. - Separate request/response and source serializers with
System.Text.Jsoncontext factories, so you can plug in generatedJsonSerializerContexttypes 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 | Versions 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. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial release of the handcrafted ManticoreSearch .NET client targeting .NET 8 and .NET 10.