SplatDev.Search 1.0.2

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

SplatDev.Search

Provider-agnostic search abstractions for SplatDev packages — contracts for indexing documents, running queries, faceting, and autocomplete across Elasticsearch, OpenSearch, Meilisearch, and other backends.

NuGet License: MIT

Compatibility

.NET Umbraco Package Version
8.0 13 1.0.0
10.0 17 1.0.0

Positioning

SplatDev.Search is the out-of-process domain search layer. It is designed for cross-site aggregate data, product catalogs, user records, and analytics — any data that lives outside the CMS content tree.

SplatDev.Umbraco.Examine remains the in-process Lucene-based search for CMS content. Both packages coexist and serve different purposes:

Concern SplatDev.Umbraco.Examine SplatDev.Search
Scope CMS content (in-process) Domain data (out-of-process)
Engine Lucene.NET Elasticsearch / OpenSearch / Meilisearch
Mapping Umbraco property editors Attribute-driven POCO mapping
Facets Limited First-class facet support
Index management Umbraco-managed Migration-driven (ISearchMigration)

Installation

dotnet add package SplatDev.Search

Interfaces

ISearchIndex<TDoc>

Index management for typed documents:

public interface ISearchIndex<TDoc> where TDoc : class
{
    Task IndexAsync(TDoc doc, CancellationToken ct = default);
    Task IndexManyAsync(IEnumerable<TDoc> docs, CancellationToken ct = default);
    Task DeleteAsync(string id, CancellationToken ct = default);
    Task DeleteByQueryAsync(SearchQuery query, CancellationToken ct = default);
    Task<RefreshResult> RefreshAsync(CancellationToken ct = default);
}

ISearchProvider<TDoc>

Query and analysis operations:

public interface ISearchProvider<TDoc> where TDoc : class
{
    Task<SearchResult<TDoc>> SearchAsync(SearchQuery query, CancellationToken ct = default);
    Task<AutocompleteResult> AutocompleteAsync(string prefix, AutocompleteOptions? opts = null, CancellationToken ct = default);
    Task<IReadOnlyList<Facet>> FacetsAsync(SearchQuery query, IEnumerable<string> fields, CancellationToken ct = default);
}

ISearchMigration

Index lifecycle management:

public interface ISearchMigration
{
    Task EnsureIndexAsync(IndexDefinition definition, CancellationToken ct = default);
    Task DropIndexAsync(string indexName, CancellationToken ct = default);
}

ISearchSerializer

Pluggable document serialization:

public interface ISearchSerializer
{
    string? Serialize<T>(T? value);
    T? Deserialize<T>(string? json);
}

Models

SearchQuery — Fluent Builder

var query = new SearchQuery()
    .WithText("running shoes")
    .Where("brand").Eq("adidas")
    .Where("category").In(["footwear", "athletic"])
    .Where("price").Range(50, 150)
    .OrderBy("rating", SortDirection.Desc)
    .Page(0, 20)
    .WithHighlight(new HighlightOptions { Fields = ["name", "description"] })
    .WithRefresh(RefreshPolicy.None);

SearchResult<TDoc>

public sealed class SearchResult<TDoc> where TDoc : class
{
    public IReadOnlyList<TDoc> Documents { get; init; }
    public long Total { get; init; }
    public int From { get; init; }
    public int Size { get; init; }
    public IReadOnlyList<Facet> Facets { get; init; }
    public IReadOnlyDictionary<string, IReadOnlyList<string>>? Highlights { get; init; }
    public long TookMs { get; init; }
}

IndexDefinition — Attribute-Driven Mapping

Annotate your POCO and derive the mapping automatically:

public class Product
{
    [SearchField(Type = FieldType.Keyword)]
    public string Id { get; set; }

    [SearchField(Type = FieldType.Text, Analyzer = "standard")]
    public string Name { get; set; }

    [SearchField(Type = FieldType.Double, Sortable = true, Facetable = true)]
    public double Price { get; set; }

    [SearchField(Type = FieldType.Keyword, Facetable = true)]
    public string Category { get; set; }
}

var def = IndexDefinition.FromType<Product>();

SearchOptions

public class SearchOptions
{
    public string IndexPrefix { get; set; } = "splatdev";
    public string KeySeparator { get; set; } = "-";
    public RefreshPolicy DefaultRefresh { get; set; } = RefreshPolicy.None;
    public bool ThrowOnEmptyIndex { get; set; }
    public int BulkChunkSize { get; set; } = 500;
}

Enums

Enum Values
RefreshPolicy None, WaitFor, Immediate
FieldOp Eq, Neq, In, Range, Exists
FieldType Text, Keyword, Long, Integer, Short, Byte, Double, Float, Boolean, Date, GeoPoint
SortDirection Asc, Desc

Dependency Injection

services.AddSplatDevSearchAbstractions(configuration);

Binds SearchOptions from "SplatDev:Search" config section and registers:

  • SearchOptions (singleton)
  • ISearchSerializerSystemTextJsonSearchSerializer (singleton)

Note: ISearchProvider<TDoc> and ISearchIndex<TDoc> are NOT registered — you must add a provider package (e.g. SplatDev.Search.Elastic).

Configuration

{
  "SplatDev": {
    "Search": {
      "IndexPrefix": "myapp",
      "KeySeparator": "-",
      "DefaultRefresh": "None",
      "BulkChunkSize": 500
    }
  }
}

Available provider implementations

Package Backend Description
SplatDev.Search.Elastic Elasticsearch 8+ Full-text search with aggregations
SplatDev.Search.OpenSearch OpenSearch 2+ AWS-compatible with optional SigV4
SplatDev.Search.Meilisearch Meilisearch Typo-tolerant search with two-key model

Design decisions

  • Single-index v1: Multi-index cross-search deferred to v2.
  • Refresh default: None with per-call override via SearchQuery.WithRefresh().
  • Vector/kNN: Deferred to v2 (SplatDev.Search.Vector.*).
  • Highlighting: Common HighlightOptions DTO with provider-specific escape hatch.
  • Bulk chunking: Foundation BulkChunkSize = 500, honored by adapters.
  • Attribute-driven mapping: Default approach with explicit IndexDefinition override supported.

Dependencies

  • Microsoft.Extensions.DependencyInjection.Abstractions
  • Microsoft.Extensions.Configuration.Abstractions
  • Microsoft.Extensions.Configuration.Binder

SplatDev.Search — part of the SplatDev.Umbraco.Plugins suite. Licensed under MIT. © SplatDev Ltda.

Changelog

1.0.2 — 2026-08-24

Removes a dashboard screenshot that showed an error toast. It was captured against a site where this plugin's API was unreachable, so it advertised a broken dashboard. No screenshot is better than a misleading one; a replacement will be taken against a working install.

1.0.1 — 2026-08-24

Package metadata only: the listing now carries an icon and search tags, and the project and repository links point at the organisation that actually hosts this code. No code changes.

1.0.0 — 2026-08-24

This package now keeps a changelog. Earlier releases predate it and are not reconstructed here — consult the repository history for those. From this version on, every release records what changed for someone using it.

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 (3)

Showing the top 3 NuGet packages that depend on SplatDev.Search:

Package Downloads
SplatDev.Search.Meilisearch

Meilisearch adapter for SplatDev.Search abstractions. Lightweight, typo-tolerant full-text search with instant indexing.

SplatDev.Search.Elastic

Elasticsearch 8+ adapter for SplatDev.Search abstractions. Full-text search, aggregations, filtering, and sorting via the official Elastic.Clients.Elasticsearch SDK.

SplatDev.Search.OpenSearch

OpenSearch adapter for SplatDev.Search abstractions. AWS-hosted or self-hosted OpenSearch with full-text search, filtering, sorting, and aggregation support.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 126 8/24/2026