Market Basket Analysis β€” Itemset Mining as a Query

Which items are bought together more than chance predicts? Classic market basket analysis means exporting transactions and running an association-rules job offline. In Aito v2 it's one query: relate {"$patterns": …} mines variable-size itemsets directly from array, set, or analyzed-text columns β€” live, on the current data, scoped by any where.

Mine co-occurring attributes

Items are the field's members. On a product catalog with a tags array:

{
  "from": "products",
  "relate": { "$patterns": ["tags"] }
}
{ "offset": 0, "total": 9, "hits": [
  { "related": { "$and": [ { "tags": { "$has": "food" } }, { "tags": { "$has": "meat" } },
                           { "tags": { "$has": "protein" } } ] },
    "f": 6, "n": 42 },
  { "related": { "$and": [ { "tags": { "$has": "gluten" } }, { "tags": { "$has": "bread" } } ] },
    "f": 5, "n": 42 },
  { "related": { "$and": [ { "tags": { "$has": "lactose" } }, { "tags": { "$has": "candy" } } ] },
    "f": 3, "n": 42 } ] }

Itemsets grow greedily while the information gain holds (up to 6 items, support β‰₯ 2) β€” you get {food, meat, protein} as one pattern, not three overlapping pairs.

Mine recurring purchase baskets

On transaction data (visits.purchases β€” the products bought per visit), the same query surfaces the repeating baskets:

{
  "from": "visits",
  "relate": { "$patterns": ["purchases"] }
}

Each hit is a set of products that recur together across visits, with its support count f and population n β€” the raw material for bundle offers, shelf placement, and cross-sell rules.

Condition on an outcome

Add a where and each itemset is scored against it β€” "which item combinations are associated with a purchase / a churn event / a delay":

{
  "from": "visits",
  "where": { "weekday": "Saturday" },
  "relate": { "$patterns": ["purchases"] }
}

Hits then carry lift and info against the condition, ranking the patterns by how strongly they predict it β€” association, not just frequency.

Scope it per client

The multi-tenant form composes: a nested from restricts the population first, so support counts and n are computed within one tenant's data:

{
  "from": { "from": "visits", "where": { "user": "larry" } },
  "relate": { "$patterns": ["purchases"] }
}

Why Aito for this

  • No export, no batch job β€” mining runs on the live collection; the patterns update as data arrives.
  • Members, not whole values: array elements, set members, and analyzed text tokens all count as items.
  • MDL-guarded growth β€” itemsets extend only while the compression gain holds, so you get few, meaningful patterns instead of a combinatorial dump.

Related: Query Reference Β· Sandbox

← All v2 use cases