DEV Community

Cover image for LioranDB TypeScript Series #7: Building Aggregation Pipelines in TypeScript
Swaraj Puppalwar
Swaraj Puppalwar

Posted on

LioranDB TypeScript Series #7: Building Aggregation Pipelines in TypeScript

LioranDB TypeScript Series #7: Building Aggregation Pipelines in TypeScript

LioranDB TypeScript Series: Build with a developer-first document database powered by Rust and designed for TypeScript.

CRUD gets data in and out.

Aggregation starts turning those documents into answers.

Your first pipeline

Suppose our products contain:

{
  title: string;
  category: string;
  price: number;
  inStock: boolean;
}
Enter fullscreen mode Exit fullscreen mode

We want to count available products by category.

const results = await products.aggregate([
  {
    $match: {
      inStock: true,
    },
  },
  {
    $group: {
      _id: "$category",
      count: {
        $sum: 1,
      },
    },
  },
]).toArray();
Enter fullscreen mode Exit fullscreen mode

Conceptually:

Documents
   ↓
$match
   ↓
$group
   ↓
Result
Enter fullscreen mode Exit fullscreen mode

Add projection

const results = await products.aggregate([
  {
    $match: {
      inStock: true,
    },
  },
  {
    $group: {
      _id: "$category",
      count: {
        $sum: 1,
      },
    },
  },
  {
    $project: {
      category: "$_id",
      count: 1,
      _id: 0,
    },
  },
  {
    $limit: 50,
  },
]).toArray();
Enter fullscreen mode Exit fullscreen mode

Current verified stages

In the current pre-alpha release:

  • $match
  • $group
  • $project
  • $skip
  • $limit

are the core documented/verified stages.

The aggregation API is intentionally still evolving.

AggregationCursor behavior

aggregate() returns an AggregationCursor.

const cursor = products.aggregate(pipeline);

const results = await cursor.toArray();
Enter fullscreen mode Exit fullscreen mode

One important implementation detail in the current driver is that the aggregation result is materialized when the cursor initially loads.

For very large result sets, don't automatically treat aggregation like incremental find() pagination.

When should I use find() instead?

If all you're doing is:

  • filtering
  • projection
  • pagination
  • limiting records

then find() may be the simpler tool.

Use aggregation when you're actually transforming or grouping data.

Need documents?
    → find()

Need derived results?
    → aggregate()
Enter fullscreen mode Exit fullscreen mode

Pre-alpha limitations are intentional

This is one area where the API will become substantially richer over time.

I'd rather document the stages that work today than publish a giant MongoDB compatibility table containing features that don't exist yet.

Pre-alpha should be explicit about its edges.

Resources

Documentation: https://docs.liorandb.com
Website: https://liorandb.com
Driver: @liorandb/driver@2.0.5


Previous: Part 6 → Indexes
Next: Part 8 → Authentication, Users, Roles & Sessions


Enter fullscreen mode Exit fullscreen mode

Top comments (0)