Skip to content

B⋈G

Think in Relations. Query Any Data.

Use it in your projects

Works with any data

Arrays, CSV files, JSON, Redis, SQL databases — same operations everywhere.

# In-memory array
purchases = Bmg::Relation.new([
{ product_id: 1, quantity: 5, type: 'sale' },
{ product_id: 2, quantity: 3, type: 'sample' },
])
# Or load from CSV
purchases = Bmg.csv("purchases.csv")
# Or connect to a SQL database
purchases = Bmg.sequel(:purchases, db)
# Same operations, any source
purchases
.restrict(Predicate.neq(:type, 'sample'))
.summarize([:product_id], quantity: :sum)

What is it good for?

Think in relations

Relational algebra gives you a powerful mental model for data manipulation. Chain operations naturally.

Query anything

Same operations work on arrays, files, Redis, or SQL. Your code doesn’t change when your data source does.

Compose freely

Extract, reuse, and combine query fragments. Build complex transformations from simple pieces.

Drop in anywhere

Works alongside ActiveRecord, Sequel, or standalone. No framework lock-in.

SQL Compilation

When your data lives in a database, Bmg compiles your queries to efficient SQL. Currently available in Ruby — coming soon to TypeScript.

suppliers
.restrict(Predicate.eq(:city, "Paris"))
.join(supplies, [:sid])
.project([:name, :qty])

SELECT DISTINCT `t2`.`qty`, `t1`.`name`
FROM `suppliers` AS 't1'
INNER JOIN `supplies` AS 't2'
ON (`t1`.`sid` = `t2`.`sid`)
WHERE (`t1`.`city` = 'Paris')

See more in our SQL vs. Bmg cheatsheet.

Created with ♥️ byEnspirit logoEnspirit logo