Tristan Kenney
01/28/2025, 4:40 AMads
and products
, where each ads
has many products
We are currently testing 10,000 ads
(with each ads
having 1000 associated products
) on Typesense Cloud Instance (16GB @ 8vCPU)
We are seeing great performance when filtering directly on either ads
or products
collections, but performance declines steeply when filtering ads
via a join to products
Is the most performant approach going to be to lift properties up onto the ads
collection, or another approach?Kishore Nallan
01/28/2025, 4:44 AMTristan Kenney
01/28/2025, 4:51 AM{
"created_at": 1738025937,
"default_sorting_field": "weighting",
"enable_nested_fields": true,
"fields": [
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "associated_skus",
"optional": true,
"reference": "products.sku",
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "ad_id",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "dynamic_search_terms",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "search_key",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "bid_amount",
"optional": true,
"sort": true,
"stem": false,
"store": true,
"type": "float"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "currency",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "weighting",
"optional": false,
"range_index": true,
"sort": true,
"stem": false,
"store": true,
"type": "float"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "over_paced",
"optional": false,
"sort": true,
"stem": false,
"store": true,
"type": "bool"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "monetization_type",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "delivery_type",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "media_type",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "locations",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "link_url",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "creatives",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "object[]"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "creatives.src",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "creatives.label",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "creatives.dimensions",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "object[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "creatives.dimensions.width",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "int32[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "creatives.dimensions.height",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "int32[]"
}
],
"name": "banner_ads",
"num_documents": 100000,
"symbols_to_index": [],
"token_separators": []
}
Tristan Kenney
01/28/2025, 4:51 AMproducts
{
"created_at": 1738025937,
"default_sorting_field": "",
"enable_nested_fields": true,
"fields": [
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "sku",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "title",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "description",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "search_key",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "category_paths",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "search_terms",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string[]"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "google_product_category",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "link",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "image_link",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "additional_image_link",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": false,
"infix": false,
"locale": "",
"name": "video_link",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "brand",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "store_id",
"optional": true,
"sort": true,
"stem": false,
"store": true,
"type": "int32"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "object"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "price",
"optional": false,
"range_index": true,
"sort": true,
"stem": false,
"store": true,
"type": "float"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "currency",
"optional": false,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "sale_price",
"optional": true,
"range_index": true,
"sort": true,
"stem": false,
"store": true,
"type": "float"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "availability",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "on_sale",
"optional": false,
"sort": true,
"stem": false,
"store": true,
"type": "bool"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "color",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "gender",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "size",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "condition",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "age_group",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_9",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_8",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_7",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_6",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_5",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_4",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_3",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_1",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_2",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "attributes.attribute_0",
"optional": true,
"sort": false,
"stem": false,
"store": true,
"type": "string"
}
],
"name": "products",
"num_documents": 500000,
"symbols_to_index": [],
"token_separators": []
}
Tristan Kenney
01/28/2025, 4:57 AM{
"collection": "banner_ads",
"q": "*",
"query_by": "locations",
"exclude_fields": "$products(*, additional_image_link, google_product_category, image_link, link, video_link, item_group_id), associated_skus",
"filter_by": "weighting:>0 && ((search_key:`Cheese` || locations:=`<https://weary-tremor.net/>`) || $products(search_key:`Cheese`))"
}
Tristan Kenney
01/28/2025, 4:59 AMKishore Nallan
01/28/2025, 6:32 AMTristan Kenney
01/28/2025, 9:10 PMbanner_ads
has been tested at various sizes, but predominantly 10K
products
is 500K (with each banner_ads
have 1K associated products
)Tristan Kenney
01/29/2025, 4:10 AMHarpreet Sangar
01/29/2025, 4:38 AM(search_key:`Cheese` || ...) || $products(search_key:`Cheese`)
If the search_key
of banner_ads
is already associated with the correct products through associated_skus
field, we can omit the join in the filter by.
{
"collection": "banner_ads",
"q": "*",
"query_by": "locations",,
"filter_by": "weighting:>0 && (search_key:`Cheese` || locations:=`<https://weary-tremor.net/>`)"
"include_fields": "$products(...)
}
Since you're querying banner_ads
collection that has the reference field, you can include the referenced documents without specifying join in the filter_by
.Tristan Kenney
01/29/2025, 5:30 AMsearch_key
is a property on both products
and banner_ads
(and we're interested in filtering on both). Wouldn't I need to specify $products(search_key...)
to filter by the property on products collection?Harpreet Sangar
01/29/2025, 5:41 AMbanner_ads(id, search_key, associated_skus)
1, Cheese, [1, 2, 5]
2, Milk, [4]
3, Curd, [3]
products(id, title, search_key)
1, prod_1, Cheese
2, prod_2, Cheese
3, prod_3, Curd
4, prod_4, Milk
5, prod_5, Cheese
and we're interested in getting the banner_ads
where the search_key
is Cheese
, both
filter_by: (search_key:`Cheese` || ...) || $products(search_key:`Cheese`)
and
filter_by: search_key:`Cheese`
will produce the same result but the former query will take longer.
If this is not your case or you'd want to join on a different search_key
, then this optimization won't work.Harpreet Sangar
01/29/2025, 5:44 AMinclude_fields: $products(...)
too.Tristan Kenney
01/29/2025, 5:46 AMbanner_ads(id, search_key, associated_skus)
1, Cheese, [1, 2, 5]
2, Milk, [4]
3, Curd, [3]
products(id, title, search_key)
1, prod_1, Parmesan
2, prod_2, Gouda
3, prod_3, Lemon
4, prod_4, Full Fat
5, prod_5, Feta
Which I presume won't work?Harpreet Sangar
01/29/2025, 5:57 AMfilter_by: search_key:`Cheese`,
include_fields: $products(...)
you'll get
Cheese {
Parmesan,
Gouda,
Feta
}
in the result. But if you want to execute a query say, having banner_ads
search_key:`Cheese` or having products
search_key:`Lemon`, then you'll have no other option.Tristan Kenney
01/29/2025, 6:02 AMHarpreet Sangar
01/29/2025, 6:10 AMinclude_fields
.