gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/query_aggregation.go (about)

     1  package rethinkdb
     2  
     3  import p "gopkg.in/rethinkdb/rethinkdb-go.v6/ql2"
     4  
     5  // Aggregation
     6  // These commands are used to compute smaller values from large sequences.
     7  
     8  // Reduce produces a single value from a sequence through repeated application
     9  // of a reduction function
    10  //
    11  // It takes one argument of type `func (r.Term, r.Term) interface{}`, for
    12  // example this query sums all elements in an array:
    13  //
    14  //     r.Expr([]int{1,3,6}).Reduce(func (left, right r.Term) interface{} {
    15  //         return left.Add(right)
    16  //     })
    17  func (t Term) Reduce(args ...interface{}) Term {
    18  	return constructMethodTerm(t, "Reduce", p.Term_REDUCE, funcWrapArgs(args), map[string]interface{}{})
    19  }
    20  
    21  // DistinctOpts contains the optional arguments for the Distinct term
    22  type DistinctOpts struct {
    23  	Index interface{} `rethinkdb:"index,omitempty"`
    24  }
    25  
    26  func (o DistinctOpts) toMap() map[string]interface{} {
    27  	return optArgsToMap(o)
    28  }
    29  
    30  // Distinct removes duplicate elements from the sequence.
    31  func Distinct(arg interface{}, optArgs ...DistinctOpts) Term {
    32  	opts := map[string]interface{}{}
    33  	if len(optArgs) >= 1 {
    34  		opts = optArgs[0].toMap()
    35  	}
    36  	return constructRootTerm("Distinct", p.Term_DISTINCT, []interface{}{arg}, opts)
    37  }
    38  
    39  // Distinct removes duplicate elements from the sequence.
    40  func (t Term) Distinct(optArgs ...DistinctOpts) Term {
    41  	opts := map[string]interface{}{}
    42  	if len(optArgs) >= 1 {
    43  		opts = optArgs[0].toMap()
    44  	}
    45  	return constructMethodTerm(t, "Distinct", p.Term_DISTINCT, []interface{}{}, opts)
    46  }
    47  
    48  // GroupOpts contains the optional arguments for the Group term
    49  type GroupOpts struct {
    50  	Index interface{} `rethinkdb:"index,omitempty"`
    51  	Multi interface{} `rethinkdb:"multi,omitempty"`
    52  }
    53  
    54  func (o GroupOpts) toMap() map[string]interface{} {
    55  	return optArgsToMap(o)
    56  }
    57  
    58  // Group takes a stream and partitions it into multiple groups based on the
    59  // fields or functions provided. Commands chained after group will be
    60  // called on each of these grouped sub-streams, producing grouped data.
    61  func Group(fieldOrFunctions ...interface{}) Term {
    62  	return constructRootTerm("Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{})
    63  }
    64  
    65  // MultiGroup takes a stream and partitions it into multiple groups based on the
    66  // fields or functions provided. Commands chained after group will be
    67  // called on each of these grouped sub-streams, producing grouped data.
    68  //
    69  // Unlike Group single documents can be assigned to multiple groups, similar
    70  // to the behavior of multi-indexes. When the grouping value is an array, documents
    71  // will be placed in each group that corresponds to the elements of the array. If
    72  // the array is empty the row will be ignored.
    73  func MultiGroup(fieldOrFunctions ...interface{}) Term {
    74  	return constructRootTerm("Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
    75  		"multi": true,
    76  	})
    77  }
    78  
    79  // GroupByIndex takes a stream and partitions it into multiple groups based on the
    80  // fields or functions provided. Commands chained after group will be
    81  // called on each of these grouped sub-streams, producing grouped data.
    82  func GroupByIndex(index interface{}, fieldOrFunctions ...interface{}) Term {
    83  	return constructRootTerm("Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
    84  		"index": index,
    85  	})
    86  }
    87  
    88  // MultiGroupByIndex takes a stream and partitions it into multiple groups based on the
    89  // fields or functions provided. Commands chained after group will be
    90  // called on each of these grouped sub-streams, producing grouped data.
    91  //
    92  // Unlike Group single documents can be assigned to multiple groups, similar
    93  // to the behavior of multi-indexes. When the grouping value is an array, documents
    94  // will be placed in each group that corresponds to the elements of the array. If
    95  // the array is empty the row will be ignored.
    96  func MultiGroupByIndex(index interface{}, fieldOrFunctions ...interface{}) Term {
    97  	return constructRootTerm("Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
    98  		"index": index,
    99  		"mutli": true,
   100  	})
   101  }
   102  
   103  // Group takes a stream and partitions it into multiple groups based on the
   104  // fields or functions provided. Commands chained after group will be
   105  // called on each of these grouped sub-streams, producing grouped data.
   106  func (t Term) Group(fieldOrFunctions ...interface{}) Term {
   107  	return constructMethodTerm(t, "Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{})
   108  }
   109  
   110  // MultiGroup takes a stream and partitions it into multiple groups based on the
   111  // fields or functions provided. Commands chained after group will be
   112  // called on each of these grouped sub-streams, producing grouped data.
   113  //
   114  // Unlike Group single documents can be assigned to multiple groups, similar
   115  // to the behavior of multi-indexes. When the grouping value is an array, documents
   116  // will be placed in each group that corresponds to the elements of the array. If
   117  // the array is empty the row will be ignored.
   118  func (t Term) MultiGroup(fieldOrFunctions ...interface{}) Term {
   119  	return constructMethodTerm(t, "Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
   120  		"multi": true,
   121  	})
   122  }
   123  
   124  // GroupByIndex takes a stream and partitions it into multiple groups based on the
   125  // fields or functions provided. Commands chained after group will be
   126  // called on each of these grouped sub-streams, producing grouped data.
   127  func (t Term) GroupByIndex(index interface{}, fieldOrFunctions ...interface{}) Term {
   128  	return constructMethodTerm(t, "Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
   129  		"index": index,
   130  	})
   131  }
   132  
   133  // MultiGroupByIndex takes a stream and partitions it into multiple groups based on the
   134  // fields or functions provided. Commands chained after group will be
   135  // called on each of these grouped sub-streams, producing grouped data.
   136  //
   137  // Unlike Group single documents can be assigned to multiple groups, similar
   138  // to the behavior of multi-indexes. When the grouping value is an array, documents
   139  // will be placed in each group that corresponds to the elements of the array. If
   140  // the array is empty the row will be ignored.
   141  func (t Term) MultiGroupByIndex(index interface{}, fieldOrFunctions ...interface{}) Term {
   142  	return constructMethodTerm(t, "Group", p.Term_GROUP, funcWrapArgs(fieldOrFunctions), map[string]interface{}{
   143  		"index": index,
   144  		"mutli": true,
   145  	})
   146  }
   147  
   148  // Ungroup takes a grouped stream or grouped data and turns it into an array of
   149  // objects representing the groups. Any commands chained after Ungroup will
   150  // operate on this array, rather than operating on each group individually.
   151  // This is useful if you want to e.g. order the groups by the value of their
   152  // reduction.
   153  func (t Term) Ungroup(args ...interface{}) Term {
   154  	return constructMethodTerm(t, "Ungroup", p.Term_UNGROUP, args, map[string]interface{}{})
   155  }
   156  
   157  // Contains returns whether or not a sequence contains all the specified values,
   158  // or if functions are provided instead, returns whether or not a sequence
   159  // contains values matching all the specified functions.
   160  func Contains(args ...interface{}) Term {
   161  	return constructRootTerm("Contains", p.Term_CONTAINS, funcWrapArgs(args), map[string]interface{}{})
   162  }
   163  
   164  // Contains returns whether or not a sequence contains all the specified values,
   165  // or if functions are provided instead, returns whether or not a sequence
   166  // contains values matching all the specified functions.
   167  func (t Term) Contains(args ...interface{}) Term {
   168  	return constructMethodTerm(t, "Contains", p.Term_CONTAINS, funcWrapArgs(args), map[string]interface{}{})
   169  }
   170  
   171  // Aggregators
   172  // These standard aggregator objects are to be used in conjunction with Group.
   173  
   174  // Count the number of elements in the sequence. With a single argument,
   175  // count the number of elements equal to it. If the argument is a function,
   176  // it is equivalent to calling filter before count.
   177  func Count(args ...interface{}) Term {
   178  	return constructRootTerm("Count", p.Term_COUNT, funcWrapArgs(args), map[string]interface{}{})
   179  }
   180  
   181  // Count the number of elements in the sequence. With a single argument,
   182  // count the number of elements equal to it. If the argument is a function,
   183  // it is equivalent to calling filter before count.
   184  func (t Term) Count(args ...interface{}) Term {
   185  	return constructMethodTerm(t, "Count", p.Term_COUNT, funcWrapArgs(args), map[string]interface{}{})
   186  }
   187  
   188  // Sum returns the sum of all the elements of a sequence. If called with a field
   189  // name, sums all the values of that field in the sequence, skipping elements of
   190  // the sequence that lack that field. If called with a function, calls that
   191  // function on every element of the sequence and sums the results, skipping
   192  // elements of the sequence where that function returns null or a non-existence
   193  // error.
   194  func Sum(args ...interface{}) Term {
   195  	return constructRootTerm("Sum", p.Term_SUM, funcWrapArgs(args), map[string]interface{}{})
   196  }
   197  
   198  // Sum returns the sum of all the elements of a sequence. If called with a field
   199  // name, sums all the values of that field in the sequence, skipping elements of
   200  // the sequence that lack that field. If called with a function, calls that
   201  // function on every element of the sequence and sums the results, skipping
   202  // elements of the sequence where that function returns null or a non-existence
   203  // error.
   204  func (t Term) Sum(args ...interface{}) Term {
   205  	return constructMethodTerm(t, "Sum", p.Term_SUM, funcWrapArgs(args), map[string]interface{}{})
   206  }
   207  
   208  // Avg returns the average of all the elements of a sequence. If called with a field
   209  // name, averages all the values of that field in the sequence, skipping elements of
   210  // the sequence that lack that field. If called with a function, calls that function
   211  // on every element of the sequence and averages the results, skipping elements of the
   212  // sequence where that function returns null or a non-existence error.
   213  func Avg(args ...interface{}) Term {
   214  	return constructRootTerm("Avg", p.Term_AVG, funcWrapArgs(args), map[string]interface{}{})
   215  }
   216  
   217  // Avg returns the average of all the elements of a sequence. If called with a field
   218  // name, averages all the values of that field in the sequence, skipping elements of
   219  // the sequence that lack that field. If called with a function, calls that function
   220  // on every element of the sequence and averages the results, skipping elements of the
   221  // sequence where that function returns null or a non-existence error.
   222  func (t Term) Avg(args ...interface{}) Term {
   223  	return constructMethodTerm(t, "Avg", p.Term_AVG, funcWrapArgs(args), map[string]interface{}{})
   224  }
   225  
   226  // MinOpts contains the optional arguments for the Min term
   227  type MinOpts struct {
   228  	Index interface{} `rethinkdb:"index,omitempty"`
   229  }
   230  
   231  func (o MinOpts) toMap() map[string]interface{} {
   232  	return optArgsToMap(o)
   233  }
   234  
   235  // Min finds the minimum of a sequence. If called with a field name, finds the element
   236  // of that sequence with the smallest value in that field. If called with a function,
   237  // calls that function on every element of the sequence and returns the element
   238  // which produced the smallest value, ignoring any elements where the function
   239  // returns null or produces a non-existence error.
   240  func Min(args ...interface{}) Term {
   241  	return constructRootTerm("Min", p.Term_MIN, funcWrapArgs(args), map[string]interface{}{})
   242  }
   243  
   244  // Min finds the minimum of a sequence. If called with a field name, finds the element
   245  // of that sequence with the smallest value in that field. If called with a function,
   246  // calls that function on every element of the sequence and returns the element
   247  // which produced the smallest value, ignoring any elements where the function
   248  // returns null or produces a non-existence error.
   249  func (t Term) Min(args ...interface{}) Term {
   250  	return constructMethodTerm(t, "Min", p.Term_MIN, funcWrapArgs(args), map[string]interface{}{})
   251  }
   252  
   253  // MinIndex finds the minimum of a sequence. If called with a field name, finds the element
   254  // of that sequence with the smallest value in that field. If called with a function,
   255  // calls that function on every element of the sequence and returns the element
   256  // which produced the smallest value, ignoring any elements where the function
   257  // returns null or produces a non-existence error.
   258  func MinIndex(index interface{}, args ...interface{}) Term {
   259  	return constructRootTerm("Min", p.Term_MIN, funcWrapArgs(args), map[string]interface{}{
   260  		"index": index,
   261  	})
   262  }
   263  
   264  // MinIndex finds the minimum of a sequence. If called with a field name, finds the element
   265  // of that sequence with the smallest value in that field. If called with a function,
   266  // calls that function on every element of the sequence and returns the element
   267  // which produced the smallest value, ignoring any elements where the function
   268  // returns null or produces a non-existence error.
   269  func (t Term) MinIndex(index interface{}, args ...interface{}) Term {
   270  	return constructMethodTerm(t, "Min", p.Term_MIN, funcWrapArgs(args), map[string]interface{}{
   271  		"index": index,
   272  	})
   273  }
   274  
   275  // MaxOpts contains the optional arguments for the Max term
   276  type MaxOpts struct {
   277  	Index interface{} `rethinkdb:"index,omitempty"`
   278  }
   279  
   280  func (o MaxOpts) toMap() map[string]interface{} {
   281  	return optArgsToMap(o)
   282  }
   283  
   284  // Max finds the maximum of a sequence. If called with a field name, finds the element
   285  // of that sequence with the largest value in that field. If called with a function,
   286  // calls that function on every element of the sequence and returns the element
   287  // which produced the largest value, ignoring any elements where the function
   288  // returns null or produces a non-existence error.
   289  func Max(args ...interface{}) Term {
   290  	return constructRootTerm("Max", p.Term_MAX, funcWrapArgs(args), map[string]interface{}{})
   291  }
   292  
   293  // Max finds the maximum of a sequence. If called with a field name, finds the element
   294  // of that sequence with the largest value in that field. If called with a function,
   295  // calls that function on every element of the sequence and returns the element
   296  // which produced the largest value, ignoring any elements where the function
   297  // returns null or produces a non-existence error.
   298  func (t Term) Max(args ...interface{}) Term {
   299  	return constructMethodTerm(t, "Max", p.Term_MAX, funcWrapArgs(args), map[string]interface{}{})
   300  }
   301  
   302  // MaxIndex finds the maximum of a sequence. If called with a field name, finds the element
   303  // of that sequence with the largest value in that field. If called with a function,
   304  // calls that function on every element of the sequence and returns the element
   305  // which produced the largest value, ignoring any elements where the function
   306  // returns null or produces a non-existence error.
   307  func MaxIndex(index interface{}, args ...interface{}) Term {
   308  	return constructRootTerm("Max", p.Term_MAX, funcWrapArgs(args), map[string]interface{}{
   309  		"index": index,
   310  	})
   311  }
   312  
   313  // MaxIndex finds the maximum of a sequence. If called with a field name, finds the element
   314  // of that sequence with the largest value in that field. If called with a function,
   315  // calls that function on every element of the sequence and returns the element
   316  // which produced the largest value, ignoring any elements where the function
   317  // returns null or produces a non-existence error.
   318  func (t Term) MaxIndex(index interface{}, args ...interface{}) Term {
   319  	return constructMethodTerm(t, "Max", p.Term_MAX, funcWrapArgs(args), map[string]interface{}{
   320  		"index": index,
   321  	})
   322  }
   323  
   324  // FoldOpts contains the optional arguments for the Fold term
   325  type FoldOpts struct {
   326  	Emit      interface{} `rethinkdb:"emit,omitempty"`
   327  	FinalEmit interface{} `rethinkdb:"final_emit,omitempty"`
   328  }
   329  
   330  func (o FoldOpts) toMap() map[string]interface{} {
   331  	return optArgsToMap(o)
   332  }
   333  
   334  // Fold applies a function to a sequence in order, maintaining state via an
   335  // accumulator. The Fold command returns either a single value or a new sequence.
   336  //
   337  // In its first form, Fold operates like Reduce, returning a value by applying a
   338  // combining function to each element in a sequence, passing the current element
   339  // and the previous reduction result to the function. However, Fold has the
   340  // following differences from Reduce:
   341  //  - it is guaranteed to proceed through the sequence from first element to last.
   342  //  - it passes an initial base value to the function with the first element in
   343  //    place of the previous reduction result.
   344  //
   345  // In its second form, Fold operates like ConcatMap, returning a new sequence
   346  // rather than a single value. When an emit function is provided, Fold will:
   347  //  - proceed through the sequence in order and take an initial base value, as above.
   348  //  - for each element in the sequence, call both the combining function and a
   349  //    separate emitting function with the current element and previous reduction result.
   350  //  - optionally pass the result of the combining function to the emitting function.
   351  //
   352  // If provided, the emitting function must return a list.
   353  func (t Term) Fold(base, fn interface{}, optArgs ...FoldOpts) Term {
   354  	opts := map[string]interface{}{}
   355  	if len(optArgs) >= 1 {
   356  		opts = optArgs[0].toMap()
   357  	}
   358  
   359  	args := []interface{}{base, funcWrap(fn)}
   360  
   361  	return constructMethodTerm(t, "Fold", p.Term_FOLD, args, opts)
   362  }