NAME
AmberDB::Index::Facet - High-Performance Columnar Facet Indexing, Disjunctive Counting, and Menu Generation for AmberDB
SYNOPSIS
# Schema definition in your .table file:
{
name => "Özellikler ve Nitelikler",
use_facet => 1,
use_junk => 1,
junk_rules => [
[ 5, "ne", 1 ], # Out-of-sale products are excluded from facet
[ "2->14", "ne", 1 ], # Inactive manufacturer products are excluded
],
facet_block => [
{ blk => 1, id => "cat", label => "Kategori", table => "catalog_category", name_idx => 2 },
{ blk => 2, id => "firm", label => "Firma", table => "catalog_producer", name_idx => 2, filter_block => [ 14, "eq", 1 ] },
{ blk => 3, id => "auth", label => "Yazar", table => "catalog_contributor", name_idx => 2 },
{ blk => 4, id => "price", label => "Fiyat Dilimi" },
{ blk => 5, id => "status", label => "Satış Durumu", required => 1 },
],
}
# Querying from AmberDB ($dbp inherits AmberDB::Index::Facet):
# 1. Standard full-catalog or filtered facet menu:
my $menu_data = $dbp->facet_menu("catalog_attributes", \%selected, \@facet_defs, \%opts);
# 2. Dynamic Scope facet menu (e.g. within search results or category scope):
my $search_facets = $dbp->facet_menu(
"catalog_attributes",
\%selected,
\@facet_defs,
{ base_ids => \@search_result_ids }
);
DESCRIPTION
AmberDB::Index::Facet provides a column-oriented forward indexing and disjunctive facet aggregation engine designed for fast faceted navigation across large-scale catalogs.
KEY ARCHITECTURAL FEATURES
1. Columnar Per-Block Storage (_${blk}.fac)
Rather than maintaining a massive monolithic matrix file, facet data is stored in partitioned columnar forward index files: ${table_path}_${blk}.fac. Each file maps Record ID to packed value IDs (using binary or tab-separated representation), enabling fast single-column sequential scanning and random lookups.
2. Active-Only Storage Guarantee
Facet index files store only currently active records. Inactive, discontinued, or junk records are automatically filtered out during index creation and mutation via facet_rules (which integrates with junk_rules). This eliminates the overhead of scanning 100K+ historical records when computing facet counts.
3. Bidirectional String Dictionary (_${blk}.str)
Non-relational string facets (e.g. colors, features) are indexed into a bidirectional .str dictionary with distinct key namespaces:
s:StringValue->NumericID(Fast write/read conversion)n:NumericID->StringValue(Fast reverse label resolution)lastid-> Auto-increment sequence tracker
4. Dynamic Scoping (base_ids)
When faceted menus are displayed on search result pages or narrow category listings, callers pass base_ids => \@ids. The engine processes only the scoped record IDs, bypassing entire-database iteration.
5. Multi-Select Disjunctive Faceting (OR-within-block, AND-across-blocks)
Supports multi-selection where checking multiple items within the same filter group uses OR logic (showing count of remaining options), while combining across different filter groups uses AND logic.
METHODS
facet_rules($table_info, @record)
Evaluates whether a record qualifies for inclusion in facet index files. Automatically delegates to !junk_rules if use_junk is enabled on the table.
facet_add($table_path, $table_info, \@records)
Indexes active records into per-block _${blk}.fac files.
facet_modify($table_path, $table_info, \@pairs)
Handles automated index updates and active/passive transitions during record updates.
facet_del($table_path, $table_info, \@records)
Removes deleted records from all per-block _${blk}.fac files.
field_fltkeys($tableid, \%opts)
Calculates facet key counts for target block directly from active _${target_block}.fac. Automatically translates numeric dictionary IDs to human-readable strings via .str.
field_allfltkeys($tableid, \@blk_list, \@base_scope)
Calculates facet key counts across multiple active block files in a single pass.
facet_menu($tableid, \%selected, \@facet_defs, \%opts)
High-level menu builder. Performs: 1. Active filtering intersection via field_filter. 2. Disjunctive per-group count calculations. 3. Top-N limiting and sorting (by count or label). 4. Label resolution via RDBM, bidirectional .str, or schema options.
AUTHOR
Maruf Cetin <marufcetin@gmail.com>
LICENSE AND COPYRIGHT
Copyright (C) 2020-2026 Maruf Cetin.
This library is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.