Faceted filtering and category pages
This page covers faceted filtering queries for ranking items within filtered sets, such as category pages or multi-faceted search results. For query fundamentals, see Query Basics.
Faceted filtering allows you to filter items by attributes (category, price range, brand, etc.) and then rank the filtered results. This is essential for building category pages, filtered product listings, and faceted search interfaces where users can apply multiple filters and still get personalized, well-ranked results.
Basic category filtering
Filter items by a single category and rank them by popularity or other attributes.
Prerequisites
- An engine with item data configured
- Item attributes to filter on (e.g.,
category,brand,price)
Query example
Filter items by category and rank by popularity:
- ShapedQL
- JSON
from shaped import RankQueryBuilder, ColumnOrder
# Basic category filtering with popularity ranking
query = (
RankQueryBuilder()
.from_entity('item')
.retrieve(
ColumnOrder(
columns=['_derived_popular_rank ASC'],
limit=100,
where="category = 'Electronics'"
)
)
.limit(20)
.build()
)
# Example usage with client
# response = client.rank(query=query)
# items = response['items']
import { RankQueryBuilder } from '@shaped-ai/api';
// Basic category filtering with popularity ranking
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.columnOrder({
columns: [{ name: '_derived_popular_rank', ascending: true }],
limit: 100,
where: "category = 'Electronics'"
})
)
.limit(20)
.build();
// Example usage with client
// const response = await client.rank({ query });
// const items = response.items;
SELECT *
FROM column_order(columns='_derived_popular_rank ASC', limit=100)
WHERE category = 'Electronics'
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 100,
"where": "category = 'Electronics'"
}
],
"limit": 20
}
}
Personalized category pages
Combine category filtering with personalization models to show users the most relevant items within a category based on their preferences.
Prerequisites
- An engine with item data configured
- A trained scoring model (e.g.,
click_through_rate,conversion_rate) - A
user_idto personalize for - Item attributes to filter on
Query example
Filter by category and rank using a personalization model:
- ShapedQL
- JSON
from shaped import RankQueryBuilder, ColumnOrder
# Personalized category page with click_through_rate ranking
query = (
RankQueryBuilder()
.from_entity('item')
.retrieve(
ColumnOrder(
columns=['_derived_popular_rank ASC'],
limit=1000,
where="category = '$category'"
)
)
.score(
value_model='click_through_rate',
input_user_id='$user_id',
input_interactions_item_ids='$interaction_item_ids'
)
.limit(20)
.build()
)
# Example usage with client
# response = client.rank(
# query=query,
# parameters={
# 'category': 'Electronics',
# 'user_id': 'user123'
# }
# )
# items = response['items']
import { RankQueryBuilder } from '@shaped-ai/api';
// Personalized category page with click_through_rate ranking
const query = new RankQueryBuilder()
.from('item')
.retrieve(step =>
step.columnOrder({
columns: [{ name: '_derived_popular_rank', ascending: true }],
limit: 1000,
where: "category = '$category'"
})
)
.score({
valueModel: 'click_through_rate',
inputUserId: '$user_id',
inputInteractionsItemIds: '$interaction_item_ids'
})
.limit(20)
.build();
// Example usage with client
// const response = await client.rank({
// query,
// parameters: {
// category: 'Electronics',
// user_id: 'user123'
// }
// });
// const items = response.items;
SELECT *
FROM column_order(columns='_derived_popular_rank ASC', limit=1000)
WHERE category = '$category'
ORDER BY score(expression='click_through_rate', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids')
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 1000,
"where": "category = '$parameters.category'"
}
],
"score": {
"value_model": "click_through_rate",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"category": "Electronics",
"user_id": "user123",
"interaction_item_ids": ["item789", "item012"]
}
}
Combining multiple models in category pages
Use an ensemble of models to balance different signals when ranking within a category:
- ShapedQL
- JSON
- Python SDK
- TypeScript SDK
from shaped import RankQueryBuilder, ColumnOrder
# Category page with ensemble model scoring
query = (
RankQueryBuilder()
.from_entity('item')
.retrieve(
ColumnOrder(
columns=['_derived_popular_rank ASC'],
limit=1000,
where="category = '$category'"
)
)
.score(
value_model='0.7 * click_through_rate + 0.2 * similarity_score + 0.1 * (1 / (1 + item._derived_popular_rank))',
input_user_id='$user_id',
input_interactions_item_ids='$interaction_item_ids'
)
.limit(20)
.build()
)
```json
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 1000,
"where": "category = '$parameters.category'"
}
],
"score": {
"value_model": "0.6 * click_through_rate + 0.4 * conversion_rate",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"category": "Electronics",
"user_id": "user123",
"interaction_item_ids": ["item789", "item012"]
}
}
Multi-faceted filtering
Apply multiple filters simultaneously (e.g., category + price range + brand) and rank the results. This is useful for building sophisticated filtering interfaces where users can narrow down results with multiple criteria.
Prerequisites
- An engine with item data configured
- Multiple item attributes to filter on
- Optionally, a trained scoring model for personalization
Query example
Filter by multiple attributes and rank by popularity:
- ShapedQL
- JSON
SELECT *
FROM column_order(columns='_derived_popular_rank ASC', limit=1000)
WHERE category = '$category'
AND price >= $min_price
AND price <= $max_price
AND brand = '$brand'
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 1000,
"where": "category = '$parameters.category' AND price >= $parameters.min_price AND price <= $parameters.max_price AND brand = '$parameters.brand'"
}
],
"limit": 20
},
"parameters": {
"category": "Electronics",
"min_price": 50,
"max_price": 200,
"brand": "Acme"
}
}
Personalized multi-faceted filtering
Combine multiple filters with personalization to show users the most relevant items matching their filter criteria:
- ShapedQL
- JSON
SELECT *
FROM column_order(columns='_derived_popular_rank ASC', limit=1000)
WHERE category = '$category'
AND price >= $min_price
AND price <= $max_price
ORDER BY score(expression='click_through_rate + 0.1 * user.age - 0.05 * item.price + 0.2 * item.rating', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids')
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 1000,
"where": "category = '$parameters.category' AND price >= $parameters.min_price AND price <= $parameters.max_price"
}
],
"score": {
"value_model": "click_through_rate + 0.1 * user.age - 0.05 * item.price + 0.2 * item.rating",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"category": "Electronics",
"min_price": 50,
"max_price": 200,
"user_id": "user123"
}
}
Combining filters with similarity search
Retrieve candidates using similarity search within a filtered set. This is useful for "more like this" recommendations within a specific category or filtered context.
Prerequisites
- An engine with a trained embedding (e.g., ALS, content embedding)
- Item attributes to filter on
- An item or user to find similar items for
Query example
Find similar items within a specific category using content-based filtering:
- Python SDK
- TypeScript SDK
- ShapedQL
- JSON
from shaped import RankQueryBuilder, SimilarItems, Filter
# Find similar items within a specific category
query = (
RankQueryBuilder()
.from_entity('item')
.retrieve([
# Get similar items
SimilarItems(
item_ids=['$reference_item_id'],
model='content',
limit=1000
),
# Apply category filter
Filter("category = '$category'")
])
.score(
value_model='similarity_score',
input_user_id='$user_id',
input_interactions_item_ids='$interaction_item_ids'
)
.limit(20)
.build()
)
# Example usage with client
# response = client.rank(
# query=query,
# parameters={
# 'reference_item_id': 'item123',
# 'category': 'Electronics'
# }
# )
# similar_items = response['items']
import { RankQueryBuilder } from '@shaped-ai/api';
// Find similar items within a specific category
const query = new RankQueryBuilder()
.from('item')
.retrieve([
// Get similar items
step => step.similarItems({
itemIds: ['$reference_item_id'],
model: 'content',
limit: 1000
}),
// Apply category filter
step => step.filter("category = '$category'")
])
.score({
valueModel: 'similarity_score',
inputUserId: '$user_id',
inputInteractionsItemIds: '$interaction_item_ids'
})
.limit(20)
.build();
// Example usage with client
// const response = await client.rank({
// query,
// parameters: {
// reference_item_id: 'item123',
// category: 'Electronics'
// }
// });
// const similarItems = response.items;
-- Find similar items within a specific category
WITH similar_items AS (
SELECT *
FROM similar_items(
item_ids=['$reference_item_id'],
model='content',
limit=1000
)
)
SELECT *
FROM similar_items
WHERE category = '$category'
ORDER BY score(expression='similarity_score', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids') DESC
LIMIT 20;
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "similar_items",
"item_ids": ["$parameters.reference_item_id"],
"model": "content",
"limit": 1000
},
{
"type": "filter",
"where": "category = '$parameters.category'"
}
],
"score": {
"value_model": "similarity_score",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"reference_item_id": "item123",
"category": "Electronics"
}
}
Query example
Find similar items within a category:
- ShapedQL
- JSON
SELECT *
FROM similarity(embedding_ref='als_embedding',
encoder='precomputed_item',
input_item_id='$item_id', limit=50)
WHERE category = '$category'
ORDER BY score(expression='click_through_rate', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids')
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"type": "similarity",
"embedding_ref": "als_embedding",
"query_encoder": {
"type": "precomputed_item",
"input_item_id": "$parameters.item_id"
},
"limit": 50,
"where": "category = '$parameters.category'"
}
],
"score": {
"value_model": "click_through_rate",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"item_id": "item123",
"category": "Electronics",
"user_id": "user123"
}
}
Advanced: Blending retrieval scores with filters
Combine multiple retrieval strategies within a filtered set, then score using both retrieval scores and model predictions:
- ShapedQL
- JSON
SELECT *
FROM similarity(embedding_ref='als_embedding',
encoder='precomputed_user',
input_user_id='$user_id', limit=50, name='collab'),
column_order(columns='_derived_popular_rank ASC', limit=50, name='popular')
WHERE category = '$category'
ORDER BY score(expression='0.5 * retrieval.collab + 0.3 * retrieval.popular + 0.2 * click_through_rate', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids')
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"name": "collab",
"type": "similarity",
"embedding_ref": "als_embedding",
"query_encoder": {
"type": "precomputed_user",
"input_user_id": "$parameters.user_id"
},
"limit": 50,
"where": "category = '$parameters.category'"
},
{
"name": "popular",
"type": "column_order",
"columns": [{ "name": "_derived_popular_rank", "ascending": true }],
"limit": 50,
"where": "category = '$parameters.category'"
}
],
"score": {
"value_model": "0.5 * retrieval.collab + 0.3 * retrieval.popular + 0.2 * click_through_rate",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"category": "Electronics",
"user_id": "user123",
"interaction_item_ids": ["item789", "item012"]
}
}
Filtering with text search
Combine text search with attribute filtering to build search results that respect both query relevance and filter constraints:
- ShapedQL
- JSON
SELECT *
FROM text_search(query='$query_text', mode='vector',
text_embedding_ref='text_embedding', limit=50,
name='vector_search'),
text_search(query='$query_text', mode='lexical', fuzziness=2, limit=50,
name='lexical_search')
WHERE category = '$category' AND price <= $max_price
ORDER BY score(expression='0.5 * retrieval.vector_search + 0.3 * retrieval.lexical_search + 0.2 * click_through_rate', input_user_id='$user_id', input_interactions_item_ids='$interaction_item_ids')
LIMIT 20
{
"query": {
"type": "rank",
"from": "item",
"retrieve": [
{
"name": "vector_search",
"type": "text_search",
"input_text_query": "$parameters.query_text",
"mode": { "type": "vector", "text_embedding_ref": "text_embedding" },
"limit": 50,
"where": "category = '$parameters.category' AND price <= $parameters.max_price"
},
{
"name": "lexical_search",
"type": "text_search",
"input_text_query": "$parameters.query_text",
"mode": { "type": "lexical", "fuzziness_edit_distance": 2 },
"limit": 50,
"where": "category = '$parameters.category' AND price <= $parameters.max_price"
}
],
"score": {
"value_model": "0.5 * retrieval.vector_search + 0.3 * retrieval.lexical_search + 0.2 * click_through_rate",
"input_user_id": "$parameters.user_id",
"input_interactions_item_ids": "$parameters.interaction_item_ids"
},
"limit": 20
},
"parameters": {
"query_text": "laptop",
"category": "Electronics",
"max_price": 1000,
"user_id": "user123"
}
}