Facet.Search
0.0.3
See the version list below for details.
dotnet add package Facet.Search --version 0.0.3
NuGet\Install-Package Facet.Search -Version 0.0.3
<PackageReference Include="Facet.Search" Version="0.0.3" />
<PackageVersion Include="Facet.Search" Version="0.0.3" />
<PackageReference Include="Facet.Search" />
paket add Facet.Search --version 0.0.3
#r "nuget: Facet.Search, 0.0.3"
#:package Facet.Search@0.0.3
#addin nuget:?package=Facet.Search&version=0.0.3
#tool nuget:?package=Facet.Search&version=0.0.3
Facet.Search
Compile-time faceted search generation for .NET, Zero boilerplate, type-safe, and performant.
Facet.Search uses source generators to automatically create search filter classes, LINQ extension methods, facet aggregations, and metadata from your domain models, all at compile time with no runtime overhead.
Features
- Zero Boilerplate - Just add attributes to your models
- Type-Safe - All filters are compile-time checked
- Performant - Generated code is as efficient as hand-written
- Clean Architecture - No Roslyn dependencies in your runtime
- EF Core Integration - Async extensions for Entity Framework Core
- Full-Text Search - Built-in text search support
- Facet Aggregations - Automatic counting and range detection
- Frontend Metadata - Generate facet metadata for UI consumption
Installation
dotnet add package Facet.Search
For Entity Framework Core integration:
dotnet add package Facet.Search.EFCore
Quick Start
1. Define Your Model
using Facet.Search;
[FacetedSearch]
public class Product
{
public int Id { get; set; }
[FullTextSearch]
public string Name { get; set; } = null!;
[SearchFacet(Type = FacetType.Categorical, DisplayName = "Brand")]
public string Brand { get; set; } = null!;
[SearchFacet(Type = FacetType.Range, DisplayName = "Price")]
public decimal Price { get; set; }
[SearchFacet(Type = FacetType.Boolean, DisplayName = "In Stock")]
public bool InStock { get; set; }
[SearchFacet(Type = FacetType.DateRange, DisplayName = "Created Date")]
public DateTime CreatedAt { get; set; }
}
2. Use Generated Code
The source generator automatically creates:
ProductSearchFilter- Filter class with all facet propertiesProductSearchExtensions- LINQ extension methodsProductFacetResults- Aggregation resultsProductSearchMetadata- Facet metadata for frontends
using YourNamespace.Search;
// Create a filter
var filter = new ProductSearchFilter
{
Brand = ["Apple", "Samsung"],
MinPrice = 100m,
MaxPrice = 1000m,
InStock = true,
SearchText = "laptop"
};
// Apply to any IQueryable<Product>
var results = products.AsQueryable()
.ApplyFacetedSearch(filter)
.ToList();
// Get facet aggregations
var aggregations = products.AsQueryable().GetFacetAggregations();
// aggregations.Brand = { "Apple": 5, "Samsung": 3, ... }
// aggregations.PriceMin = 99.99m
// aggregations.PriceMax = 2499.99m
// Access metadata for UI
foreach (var facet in ProductSearchMetadata.Facets)
{
Console.WriteLine($"{facet.DisplayName} ({facet.Type})");
}
EF Core Integration
Use the Facet.Search.EFCore package for async operations:
using Facet.Search.EFCore;
// Async search execution
var results = await dbContext.Products
.ApplyFacetedSearch(filter)
.ExecuteSearchAsync();
// Async count
var count = await dbContext.Products
.ApplyFacetedSearch(filter)
.CountSearchResultsAsync();
// Async facet aggregation
var brandCounts = await dbContext.Products
.AggregateFacetAsync(p => p.Brand, limit: 10);
Facet Types
| Type | Description | Generated Properties |
|---|---|---|
Categorical |
Discrete values (e.g., Brand, Category) | string[]? PropertyName |
Range |
Numeric ranges (e.g., Price, Rating) | decimal? MinPropertyName, decimal? MaxPropertyName |
Boolean |
True/false filters (e.g., InStock) | bool? PropertyName |
DateRange |
Date/time ranges | DateTime? PropertyNameFrom, DateTime? PropertyNameTo |
Hierarchical |
Nested categories | string[]? PropertyName |
Attributes
[FacetedSearch]
Marks a class for search generation.
[FacetedSearch(
FilterClassName = "CustomFilter", // Custom filter class name
GenerateAggregations = true, // Generate aggregation methods
GenerateMetadata = true, // Generate metadata class
Namespace = "Custom.Namespace" // Custom namespace for generated code
)]
public class Product { }
[SearchFacet]
Marks a property as a filterable facet.
[SearchFacet(
Type = FacetType.Categorical, // Facet type
DisplayName = "Product Brand", // UI display name
OrderBy = FacetOrder.Count, // Aggregation ordering
Limit = 10, // Max aggregation values
DependsOn = "Category", // Dependent facet
IsHierarchical = false // Hierarchical category
)]
public string Brand { get; set; }
[FullTextSearch]
Marks a property for full-text search.
[FullTextSearch(
Weight = 1.0f, // Search relevance weight
CaseSensitive = false, // Case sensitivity
Behavior = TextSearchBehavior.Contains // Match behavior
)]
public string Name { get; set; }
[Searchable]
Marks a property as searchable but not a facet.
[Searchable(Sortable = true)]
public int Rating { get; set; }
Generated Code Location
Generated files appear in your project's obj folder:
obj/Debug/net8.0/generated/Facet.Search.Generators/
??? ProductSearchFilter.g.cs
??? ProductSearchExtensions.g.cs
??? ProductFacetAggregations.g.cs
??? ProductSearchMetadata.g.cs
Requirements
- .NET Standard 2.0+ (for Facet.Search)
- .NET 6.0+ (for Facet.Search.EFCore)
- C# 9.0+
License
MIT License - see LICENSE.txt for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related Projects
- Facet - The Facet ecosystem
| Product | Versions 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 was computed. 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 was computed. 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 | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Facet.Search:
| Package | Downloads |
|---|---|
|
Facet.Search.EFCore
Entity Framework Core integration for Facet.Search |
GitHub repositories
This package is not used by any popular GitHub repositories.