Velo: Working with Aggregations in the Data API
Sample Data
City, Population, State, Year
Buffalo, 292000, NY, 2000
Buffalo, 261000, NY, 2010
Los Angeles, 3703000, CA, 2000
Los Angeles, 3796000, CA, 2010
Miami, 362000, FL, 2000
Miami, 401000, FL, 2010
New York, 8015000, NY, 2000
New York, 8192000, NY, 2010
Orlando, 195000, FL, 2000
Orlando, 240000, FL, 2010
San Diego 1228000, CA, 2000
San Diego 1306000, CA, 2010
San Francisco, 777000, CA, 2000
San Francisco, 805000, CA, 2010
- Create a collection on your site named PopulationData.
- Save the above data in a .csv file.
- Import the .csv file into the PopulationData collection.
- Copy and paste the code snippets found below into the code panel on one of your sites pages.
Importing wix-data
To work with aggregations, you will need to import wix-data
.
1import wixData from 'wix-data';
Running Aggregations
To run an aggregation:
- Create an aggregation using the
aggregate()
function. - Refine the aggregation using the functions described below.
- Run the aggregation using the
run()
function. - Handle the aggregation results.
1wixData.aggregate("PopulationData")
2 .max("population")
3 .run()
4 .then( (results) => {
5 let populationMax = results.items[0].populationMax;
6 } );
You can also use the following functions with an aggregation to modify the results you receive:
Aggregation Results
To handle aggregation results, use the following properties and functions on the object returned in the aggregate()
function's Promise:
items
- An array of the aggregated items or groups. Each value is contained in an object that is an element of the array. The structure of the objects depends on which aggregations have been run.length
- The number of items or groups in the aggregate results.hasNext()
- Indicates if the aggregation has more results. Aggregation results are paged. So if your aggregation returns more results than the page size, you will have multiple pages of results.next()
- Retrieves the next page of aggregate results.
Aggregations Structure
The parts of an aggregation are explained below using the following example aggregation, which finds the cities whose population in 2010 was the largest in their respective states and the population was over 1,000,000.
1import wixData from 'wix-data';
2
3// ...
4
5const filter = wixData.filter().eq("year", 2010);
6const having = wixData.filter().gt("maxPopulation", 1000000);
7
8wixData.aggregate("PopulationData")
9 .filter(filter)
10 .group("state")
11 .max("population", "maxPopulation")
12 .having(having)
13 .descending("maxPopulation")
14 .run()
15 .then( (results) => {
16 console.log(results.items);
17 console.log(results.length);
18 console.log(results.hasNext());
19 } )
20 .catch( (error) => {
21 console.log(error.message);
22 console.log(error.code);
23 } );
filter()
Use the filter()
function to narrow down which items are included in an aggregation.
For example, on line 9 of the aggregation above, the filter is used to filter out items where the year
is not 2010
.
The aggregate filter()
function takes a WixDataFilter
object created using the wix-data.filter()
function (line 5 above). Use any of the WixDataFilter
filtering functions to build your WixDataFilter
object.
group()
Use the group()
function to group retrieved items together and then optionally calculate aggregated values and further filter the groups.
For example, without grouping you can find the city with the largest population in a collection or you can find the city with the largest population in a specific state. However, with grouping you can find the city with the largest population in each state.
For example, on line 10 of the aggregation above, grouping is used to group together all cities in the same state. Then, on line 11, the max()
function is used to get the largest population value from each of the state groups.
The group()
function can also be used to create groups based on multiple fields.
having()
Use the having()
function to narrow down which groups are included in an aggregation. The having()
function differs from filter in that it is applied after the groupings are made. So filter()
filters out items from the collection that you don't want considered at all while having()
filters out groups that don't match the given criteria.
For example, on line 12 of the aggregation above, the having is used to filter out groups where the maxPopulation
is less or equal to 1000000
.
The having()
function takes a WixDataFilter
object created using the wix-data.filter()
function (line 6 above). Use any of the WixDataFilter
filtering functions to build your WixDataFilter
object.
Sorting
Use the ascending()
and decending()
functions to sort the aggregation's resulting items or groups.
For example, on line 13 of the aggregation above, the results are sorted in descending order based on the aggregated maxPopulation
values.
You can sort based on actual fields from your collection or virtual fields that are created as part of the grouping and aggregation process. For example, the sort on line 13 above is performed on the maxPopulation
field, which is not a field in the collection, but a field created by the max()
aggregation.
Examples
max()
This example finds the largest population value of all the cities across all years. Notice that the key in the results is named "populationMax"
because we are calling the max()
function and passing it the "population"
field key.
1wixData.aggregate("PopulationData")
2 .max("population")
3 .run()
4 .then( (results) => {
5 let items = results.items;
6 } );
7
8/* items is:
9 * [{"_id": "0", "populationMax": 8192000}]
10 */
group(), max()
This example finds the largest population value in each state across all years.
1wixData.aggregate("PopulationData")
2 .group("state")
3 .max("population")
4 .run()
5 .then( (results) => {
6 let items = results.items;
7 } );
8
9/* items is:
10 * [
11 * {"_id": "FL", "populationMax": 401000},
12 * {"_id": "CA", "populationMax": 3796000},
13 * {"_id": "NY", "populationMax": 8192000}
14 * ]
15 */
group(), count()
1wixData.aggregate("PopulationData")
2 .group("state")
3 .count()
4 .run()
5 .then( (results) => {
6 let items = results.items;
7 } );
8
9/* items is:
10 * [
11 * {"_id":"FL","count":4},
12 * {"_id":"CA","count":6},
13 * {"_id":"NY","count":4}
14 * ]
15 */
group(...multiple-fields), max()
For example, here is an aggregation that finds the largest population in each state for each year with population data.
1wixData.aggregate("PopulationData")
2 .group("state", "year")
3 .max("population")
4 .run()
5 .then( (results) => {
6 let items = results.items;
7 } );
8
9/* items is:
10 * [
11 * {
12 * "_id": {"state": "NY", "year": 2000},
13 * "populationMax": 8015000,
14 * "state": "NY",
15 * "year": 2000
16 * },{
17 * "_id": {"state": "FL", "year": 2000},
18 * "populationMax": 362000,
19 * "state": "FL",
20 * "year": 2000
21 * },{
22 * "_id": {"state": "CA", "year": 2000},
23 * "populationMax": 3703000,
24 * "state": "CA",
25 * "year": 2000
26 * },{
27 * "_id": {"state": "FL", "year": 2010},
28 * "populationMax": 401000,
29 * "state": "FL",
30 * "year": 2010
31 * },{
32 * "_id": {"state": "CA", "year": 2010},
33 * "populationMax": 3796000,
34 * "state": "CA",
35 * "year": 2010
36 * },{
37 * "_id":{"state": "NY", "year": 2010},
38 * "populationMax": 8192000,
39 * "state": "NY",
40 * "year": 2010
41 * }
42 * ]
43 */
group(...multiple-fields), count()
1wixData.aggregate("PopulationData")
2 .group("state", "year")
3 .count()
4 .run()
5 .then( (results) => {
6 let items = results.items;
7 } );
8
9/* items is:
10 * [
11 * {
12 * "_id": {"state": "NY", "year": 2000},
13 * "count": 2,
14 * "state": "NY",
15 * "year": 2000
16 * },{
17 * "_id": {"state": "FL", "year": 2000},
18 * "count": 2,
19 * "state": "FL",
20 * "year": 2000
21 * },{
22 * "_id": {"state": "CA", "year": 2000},
23 * "count": 3,
24 * "state": "CA",
25 * "year": 2000
26 * },{
27 * "_id": {"state": "FL", "year": 2010},
28 * "count": 2,
29 * "state": "FL",
30 * "year": 2010
31 * },{
32 * "_id": {"state": "CA", "year": 2010},
33 * "count": 3,
34 * "state": "CA",
35 * "year": 2010
36 * },{
37 * "_id": {"state": "NY", "year": 2010},
38 * "count": 2,
39 * "state": "NY",
40 * "year": 2010
41 * }
42 * ]
43 */
44
filter(), max()
1let filter = wixData.filter().eq("year", 2000);
2
3wixData.aggregate("PopulationData")
4 .filter(filter)
5 .max("population")
6 .run()
7 .then( (results) => {
8 let items = results.items;
9 } );
10
11// items is: [{"_id": "0", "populationMax": 8015000}]
group(), max(), ascending()
This example uses a sort to find the largest population in each state across all years and sorts them from least to greatest.
1wixData.aggregate("PopulationData")
2 .group("state")
3 .max("population")
4 .ascending("populationMax")
5 .run()
6 .then( (results) => {
7 let items = results.items;
8 } );
9
10/* items is:
11 * [
12 * {"_id": "FL", "populationMax": 401000},
13 * {"_id": "CA", "populationMax": 3796000},
14 * {"_id": "NY", "populationMax": 8192000}
15 * ]
16 */