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 }