AmberDB
view release on metacpan or search on metacpan
docs/EN.AmberDB_User-Guide.md view on Meta::CPAN
```perl
# 2. HTML Tag Stripping (remove_tags)
my $text = $adb->remove_tags("<p>Description with <br/>line break</p>");
# 3. Text Truncation with Ellipsis Preservation (truncate_text / sub_str / short_title)
my $summary = $adb->truncate_text($long_body, 120); # Word-boundary safe truncation
my $short = $adb->short_title($product_title, 32); # ASCII-normalized short slug/title
# 4. Data Pattern Classifier (what_isthis)
my $type = $adb->what_isthis("user@example.com"); # Returns: 'email'
# Recognizes: email, barcode, gsm, phone, tcno, number, ascii, letter, domain, other
# 5. HTML Entity Conversion (html_ascode / code_ashtml / text2html / html2text)
my $encoded_html = $adb->html_ascode('<a href="test">'); # Encodes special characters to HTML entities
my $plain_text = $adb->html2text($html_document);
```
---
## 16. Faceted Search & Category Filters (Facet Engine)
The Facet Engine powers e-commerce sidebar filter menus (Brand, Category, Author, Price Range, Color, etc.), designed for high-performance, low-latency multi-select faceted filtering across large product catalogs.
### 16.1 Key Benefits & Features
* **Low-Latency Columnar Aggregation:** Instead of scanning full records across the entire database on every page view, the engine reads only the targeted columnar forward index files (`.fac`), aggregating filter menus with minimal I/O overhead.
* **Counts In-Stock & Active Items Only:** Discontinued, out-of-stock, or disabled products never inflate filter counts; shoppers see only genuine, purchasable options and accurate item counts.
* **Smart Multi-Select (Disjunctive Counting):** When a shopper selects multiple brands (e.g., both *Apple* and *Samsung*), remaining brand counts stay visible and accurate (OR logic within the group, AND logic across groups).
* **Search-Scoped Filters (`base_ids`):** When a visitor searches for a keyword (e.g., "wireless headphones"), the sidebar filter displays attributes only for the matching search results, rather than the entire store.
* **Automatic Label Resolution:** Numeric IDs and free-text attributes (e.g., Color names) are automatically resolved into human-readable UI labels without requiring manual join queries.
### 16.2 Schema Configuration (`.table`)
Enable the facet engine by adding `use_facet => 1` and your `facet_block` specifications to your table schema:
```perl
# dbstore/schema/catalog_attributes.table
{
name => "Product Attributes",
use_facet => 1, # Enables the facet filtering engine on this table
# Define which blocks to expose as sidebar filters:
facet_block => [
# Relational Filters (Category, Brand, Author from foreign tables):
{ blk => 1, id => "category", label => "Category", table => "catalog_category", name_idx => 2 },
{ blk => 2, id => "brand", label => "Brand", table => "catalog_producer", name_idx => 2 },
{ blk => 3, id => "author", label => "Author", table => "catalog_contributor", name_idx => 2 },
# Numeric / Range Filters:
{ blk => 4, id => "price", label => "Price Range" },
# Free-Text Attributes (Color, Size, etc.):
{ blk => 6, id => "color", label => "Color" },
],
}
```
### 16.3 Usage & Practical Examples
#### A. Building Category Sidebar Menus
Generate complete filter groups and matching product counts in a single method call:
```perl
# User selections from URL query string: Category 5, Brand 12 or 14 selected
my %selected_filters = ( 1 => "5", 2 => ["12", "14"] );
my $menu = $adb->facet_menu(
"catalog_attributes",
\%selected_filters,
$table_info->{facet_block},
{ limit => 10, sort => "count" } # Display top 10 options per group sorted by product count
);
# $menu structure is ready to pass directly to your template:
# {
# count => 42, # Total matching products
# ids => [ 101, 105, 120, ... ], # IDs of matching products for product grid
# active_counts => { 1 => 1, 2 => 2 }, # Active filters count per block
# groups => [ # Ready-to-render sidebar groups:
# {
# blk => 2,
# name => "Brand",
# active => "1",
# active_count => 2,
# records => [
# { uid => "fc_2_12", param => "f2", val => 12, label => "Apple", count => 28, checked => "1" },
# { uid => "fc_2_14", param => "f2", val => 14, label => "Samsung", count => 14, checked => "1" },
# { uid => "fc_2_19", param => "f2", val => 19, label => "Sony", count => 6, checked => "" },
# ]
# },
# ...
# ]
# }
```
#### B. Dynamic Filters on Search Result Pages
Pass the list of search result IDs as `base_ids` so sidebar filters apply strictly to search results:
```perl
# 1. Search catalog for user query (keys_only returns unpaginated ID list)
my @found_ids = $adb->search_table("catalog_product", "sci-fi", keys_only => 1);
# 2. Generate facet menu scoped exclusively to the search results
my $search_facets = $adb->facet_menu(
"catalog_attributes",
\%selected_filters,
$table_info->{facet_block},
{ base_ids => \@found_ids }
);
```
---
## 17. User Audit Trail and Backup
### 17.1 User Action History (`log_owner`)
When `log_owner => 1` is enabled in the schema, record modification history is stored in `.aut`:
```perl
# Retrieve user audit history as formatted HTML
( run in 0.986 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )