group

An array of dictionaries describing grouping options. Each item in the list should contain grouping options for each level of grouping.
Each dictionary must contain the following properties:
- field - the path to the property to group by
- order - the sorting order of the groups - "asc" or "desc". Defaults to "asc"
- aggregate - optional settings for any aggregation to apply for the items within each bottom-level group.

Grouping is applied after client-side filering.

var dataSource = new shield.DataSource({
    data: [
        { id: 1, name: "item 1", category: 2, arr: [4, "7", { id: null }] },
        { id: 2, name: "item 2", category: 1, arr: [1, "9", { id: 12 }] },
        { id: 3, name: "item 3", category: 3, arr: [5, "2", { id: "subchild 1" }] },
        { id: 4, name: "item 4", category: 2, arr: [7, "4", { id: undefined }] },
        { id: 5, name: "item 5", category: 2, arr: [2, "1", { id: null }] },
        { id: 6, name: "item 6", category: 3, arr: [3, "3", { id: "subchild 2" }] },
        { id: 7, name: "item 7", category: 1, arr: [8, "5", { id: 7 }] },
        { id: 8, name: "item 8", category: 1, arr: [10, "8", { id: "child 3" }] },
        { id: 9, name: "item 9", category: 3, arr: [9, "10", { id: "child 4" }] },
        { id: 10, name: "item 10", category: 2, arr: [6, "6", { id: "13" }] }
    ],
    group: [
        // group the items by category
        // sort the groups by their category field in ascending order
        // calculate min aggregation function for each group
        {
            field: "category", 
            order: "asc", 
            aggregate: [ 
                { field: "arr[1]", aggregate: "min" } 
            ]
        }
    ]
});

dataSource.read().then(function() {
    console.log(dataSource.view.length + " groups");
    // prints: 3 groups

    console.log("Category: " + dataSource.view[0].value);
    // prints: Category: 1
    console.log(dataSource.view[0].items.length + " items");
    // prints: 3 items
    console.log(dataSource.view[0].aggregate[0].aggregate + " - " + dataSource.view[0].aggregate[0].value);
    // prints: min 5

    console.log("Category: " + dataSource.view[1].value);
    // prints: Category: 2
    console.log(dataSource.view[1].items.length + " items");
    // prints: 4 items
    console.log(dataSource.view[1].aggregate[0].aggregate + " - " + dataSource.view[1].aggregate[0].value);
    // prints: min 1

    console.log("Category: " + dataSource.view[2].value);
    // prints: Category: 3
    console.log(dataSource.view[2].items.length + " items");
    // prints: 3 items
    console.log(dataSource.view[2].aggregate[0].aggregate + " - " + dataSource.view[2].aggregate[0].value);
    // prints: min 2
});

You can also add more than one group with more than one aggregate:

var dataSource = new shield.DataSource({
...
    group: [
         { 
                field: "ProductID", order: "asc", 
                aggregate: [
                        { field: "ProductID", aggregate: "count", type: Number }, 
                        { field: "UnitPrice", aggregate: "count", type: Number }
                ] 
        },
         { 
                field: "Discontinued", order: "asc", 
                aggregate: [
                        { field: "ProductID", aggregate: "count", type: Number }
                ]
        }
    ]
});

A live example of DataSource groups and aggregates can be found here: Grouping with aggregates