docs
Aggregation

Aggregation

PoloDB uses aggregate to process data records and return computed results. You can pass an array of aggregation stages to the aggregate method.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn count_yellow_fruits(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$match": {
                    "color": "yellow",
                },
            },
            doc! {
                "$count": "count",
            },
        ])
        .run()?
        .collect()
}

In the example above, the aggregation pipeline consists of two stages:

  • $match stage filters the documents by the color field.
  • $count stage counts the number of documents that pass through the pipeline.

Here's a list of aggregation stages that PoloDB supports:

$match

Filters the documents to pass only the documents that match the specified condition.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn find_yellow_fruits(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$match": {
                    "color": "yellow",
                },
            },
        ])
        .run()?
        .collect()
}

$count

Counts the number of documents that pass through the pipeline.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn count_fruits(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$count": "count",
            },
        ])
        .run()?
        .collect()
}

$group

Groups documents by some specified expression and outputs to the next stage a document for each distinct grouping.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn group_fruits_by_color(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$group": {
                    "_id": "$color",
                    "count": { "$sum": 1 },
                },
            },
        ])
        .run()?
        .collect()
}

$sort

Sorts all input documents and returns them to the pipeline in sorted order.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn sort_fruits_by_color(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$sort": {
                    "color": 1,
                },
            },
        ])
        .run()?
        .collect()
}

$limit

Limits the number of documents passed to the next stage in the pipeline.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn first_two_fruits(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$limit": 2,
            },
        ])
        .run()?
        .collect()
}

$skip

Skips a specified number of documents.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn skip_first_fruit(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$skip": 1,
            },
        ])
        .run()?
        .collect()
}

$addFields

Adds new fields to documents.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn add_field_to_fruits(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$addFields": {
                    "newField": "new value",
                },
            },
        ])
        .run()?
        .collect()
}

$unset

Removes fields from documents.

use polodb_core::{
    bson::{doc, Document},
    CollectionT, Database, Result,
};
 
fn remove_color_field(db: &Database) -> Result<Vec<Document>> {
    let fruits = db.collection::<Document>("fruits");
 
    fruits
        .aggregate(vec![
            doc! {
                "$unset": "color",
            },
        ])
        .run()?
        .collect()
}