github.com/MontFerret/ferret@v0.18.0/pkg/compiler/compiler_collect_aggregate_test.go (about)

     1  package compiler_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	. "github.com/smartystreets/goconvey/convey"
     8  
     9  	"github.com/MontFerret/ferret/pkg/compiler"
    10  	"github.com/MontFerret/ferret/pkg/runtime"
    11  )
    12  
    13  func TestAggregate(t *testing.T) {
    14  	Convey("Should aggregate values without grouping", t, func() {
    15  		c := compiler.New()
    16  
    17  		prog, err := c.Compile(`
    18  			LET users = [
    19  				{
    20  					active: true,
    21  					married: true,
    22  					age: 31,
    23  					gender: "m"
    24  				},
    25  				{
    26  					active: true,
    27  					married: false,
    28  					age: 25,
    29  					gender: "f"
    30  				},
    31  				{
    32  					active: true,
    33  					married: false,
    34  					age: 36,
    35  					gender: "m"
    36  				},
    37  				{
    38  					active: false,
    39  					married: true,
    40  					age: 69,
    41  					gender: "m"
    42  				},
    43  				{
    44  					active: true,
    45  					married: true,
    46  					age: 45,
    47  					gender: "f"
    48  				}
    49  			]
    50  			FOR u IN users
    51    				COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
    52    				RETURN {
    53      				minAge, 
    54      				maxAge 
    55    				}
    56  		`)
    57  
    58  		So(err, ShouldBeNil)
    59  		So(prog, ShouldHaveSameTypeAs, &runtime.Program{})
    60  
    61  		out, err := prog.Run(context.Background())
    62  
    63  		So(err, ShouldBeNil)
    64  		So(string(out), ShouldEqual, `[{"maxAge":69,"minAge":25}]`)
    65  	})
    66  
    67  	Convey("Should aggregate values without grouping with multiple arguments", t, func() {
    68  		c := compiler.New()
    69  
    70  		prog, err := c.Compile(`
    71  			LET users = [
    72  				{
    73  					active: true,
    74  					married: true,
    75  					age: 31,
    76  					gender: "m"
    77  				},
    78  				{
    79  					active: true,
    80  					married: false,
    81  					age: 25,
    82  					gender: "f"
    83  				},
    84  				{
    85  					active: true,
    86  					married: false,
    87  					age: 36,
    88  					gender: "m"
    89  				},
    90  				{
    91  					active: false,
    92  					married: true,
    93  					age: 69,
    94  					gender: "m"
    95  				},
    96  				{
    97  					active: true,
    98  					married: true,
    99  					age: 45,
   100  					gender: "f"
   101  				}
   102  			]
   103  			FOR u IN users
   104    				COLLECT AGGREGATE ages = UNION(u.age, u.age)
   105    				RETURN ages
   106  		`)
   107  
   108  		So(err, ShouldBeNil)
   109  		So(prog, ShouldHaveSameTypeAs, &runtime.Program{})
   110  
   111  		out, err := prog.Run(context.Background())
   112  
   113  		So(err, ShouldBeNil)
   114  		So(string(out), ShouldEqual, `[[31,25,36,69,45,31,25,36,69,45]]`)
   115  	})
   116  
   117  	Convey("Should aggregate values with grouping", t, func() {
   118  		c := compiler.New()
   119  
   120  		prog, err := c.Compile(`
   121  			LET users = [
   122  				{
   123  					active: true,
   124  					married: true,
   125  					age: 31,
   126  					gender: "m"
   127  				},
   128  				{
   129  					active: true,
   130  					married: false,
   131  					age: 25,
   132  					gender: "f"
   133  				},
   134  				{
   135  					active: true,
   136  					married: false,
   137  					age: 36,
   138  					gender: "m"
   139  				},
   140  				{
   141  					active: false,
   142  					married: true,
   143  					age: 69,
   144  					gender: "m"
   145  				},
   146  				{
   147  					active: true,
   148  					married: true,
   149  					age: 45,
   150  					gender: "f"
   151  				}
   152  			]
   153  			FOR u IN users
   154    				COLLECT ageGroup = FLOOR(u.age / 5) * 5 
   155    				AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
   156    				RETURN {
   157  					ageGroup,
   158      				minAge, 
   159      				maxAge 
   160    				}
   161  		`)
   162  
   163  		So(err, ShouldBeNil)
   164  		So(prog, ShouldHaveSameTypeAs, &runtime.Program{})
   165  
   166  		out, err := prog.Run(context.Background())
   167  
   168  		So(err, ShouldBeNil)
   169  		So(string(out), ShouldEqual, `[{"ageGroup":25,"maxAge":25,"minAge":25},{"ageGroup":30,"maxAge":31,"minAge":31},{"ageGroup":35,"maxAge":36,"minAge":36},{"ageGroup":45,"maxAge":45,"minAge":45},{"ageGroup":65,"maxAge":69,"minAge":69}]`)
   170  	})
   171  }
   172  
   173  func BenchmarkAggregate(b *testing.B) {
   174  	p := compiler.New().MustCompile(`
   175  			LET users = [
   176  				{
   177  					active: true,
   178  					married: true,
   179  					age: 31,
   180  					gender: "m"
   181  				},
   182  				{
   183  					active: true,
   184  					married: false,
   185  					age: 25,
   186  					gender: "f"
   187  				},
   188  				{
   189  					active: true,
   190  					married: false,
   191  					age: 36,
   192  					gender: "m"
   193  				},
   194  				{
   195  					active: false,
   196  					married: true,
   197  					age: 69,
   198  					gender: "m"
   199  				},
   200  				{
   201  					active: true,
   202  					married: true,
   203  					age: 45,
   204  					gender: "f"
   205  				}
   206  			]
   207  			FOR u IN users
   208    				COLLECT AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
   209    				RETURN {
   210      				minAge, 
   211      				maxAge 
   212    				}
   213  		`)
   214  
   215  	for n := 0; n < b.N; n++ {
   216  		p.Run(context.Background())
   217  	}
   218  }
   219  
   220  func BenchmarkAggregate2(b *testing.B) {
   221  	p := compiler.New().MustCompile(`
   222  			LET users = [
   223  				{
   224  					active: true,
   225  					married: true,
   226  					age: 31,
   227  					gender: "m"
   228  				},
   229  				{
   230  					active: true,
   231  					married: false,
   232  					age: 25,
   233  					gender: "f"
   234  				},
   235  				{
   236  					active: true,
   237  					married: false,
   238  					age: 36,
   239  					gender: "m"
   240  				},
   241  				{
   242  					active: false,
   243  					married: true,
   244  					age: 69,
   245  					gender: "m"
   246  				},
   247  				{
   248  					active: true,
   249  					married: true,
   250  					age: 45,
   251  					gender: "f"
   252  				}
   253  			]
   254  			FOR u IN users
   255    				COLLECT AGGREGATE ages = UNION(u.age, u.age)
   256    				RETURN ages
   257  		`)
   258  
   259  	for n := 0; n < b.N; n++ {
   260  		p.Run(context.Background())
   261  	}
   262  }
   263  
   264  func BenchmarkAggregate3(b *testing.B) {
   265  	p := compiler.New().MustCompile(`
   266  			LET users = [
   267  				{
   268  					active: true,
   269  					married: true,
   270  					age: 31,
   271  					gender: "m"
   272  				},
   273  				{
   274  					active: true,
   275  					married: false,
   276  					age: 25,
   277  					gender: "f"
   278  				},
   279  				{
   280  					active: true,
   281  					married: false,
   282  					age: 36,
   283  					gender: "m"
   284  				},
   285  				{
   286  					active: false,
   287  					married: true,
   288  					age: 69,
   289  					gender: "m"
   290  				},
   291  				{
   292  					active: true,
   293  					married: true,
   294  					age: 45,
   295  					gender: "f"
   296  				}
   297  			]
   298  			FOR u IN users
   299    				COLLECT ageGroup = FLOOR(u.age / 5) * 5 
   300    				AGGREGATE minAge = MIN(u.age), maxAge = MAX(u.age)
   301    				RETURN {
   302  					ageGroup,
   303      				minAge, 
   304      				maxAge 
   305    				}
   306  		`)
   307  
   308  	for n := 0; n < b.N; n++ {
   309  		p.Run(context.Background())
   310  	}
   311  }