@@ -35,17 +35,18 @@ type query struct {
3535
3636// JSONQ describes a JSONQ type which contains all the state
3737type JSONQ struct {
38- option option // contains options for JSONQ
39- queryMap map [string ]QueryFunc // contains query functions
40- node string // contains node name
41- raw json.RawMessage // raw message from source (reader, string or file)
42- rootJSONContent interface {} // original decoded json data
43- jsonContent interface {} // copy of original decoded json data for further processing
44- queryIndex int // contains number of orWhere query call
45- queries [][]query // nested queries
46- attributes []string // select attributes that will be available in final resuls
47- limitRecords int // number of records that willbe available in final result
48- errors []error // contains all the errors when processing
38+ option option // contains options for JSONQ
39+ queryMap map [string ]QueryFunc // contains query functions
40+ node string // contains node name
41+ raw json.RawMessage // raw message from source (reader, string or file)
42+ rootJSONContent interface {} // original decoded json data
43+ jsonContent interface {} // copy of original decoded json data for further processing
44+ queryIndex int // contains number of orWhere query call
45+ queries [][]query // nested queries
46+ attributes []string // select attributes that will be available in final resuls
47+ limitRecords int // number of records that willbe available in final result
48+ distinctProperty string // contain the distinct attribute name
49+ errors []error // contains all the errors when processing
4950}
5051
5152// String satisfies stringer interface
@@ -382,14 +383,18 @@ func (j *JSONQ) SortBy(order ...string) *JSONQ {
382383
383384// Distinct builds distinct value using provided attribute/column/property
384385func (j * JSONQ ) Distinct (property string ) * JSONQ {
385- j .prepare ()
386+ j .distinctProperty = property
387+ return j
388+ }
386389
390+ // distinct builds distinct value using provided attribute/column/property
391+ func (j * JSONQ ) distinct () * JSONQ {
387392 m := map [string ]bool {}
388393 dt := []interface {}{}
389394 if aa , ok := j .jsonContent .([]interface {}); ok {
390395 for _ , a := range aa {
391396 if vm , ok := a .(map [string ]interface {}); ok {
392- v , err := getNestedValue (vm , property )
397+ v , err := getNestedValue (vm , j . distinctProperty )
393398 if err != nil {
394399 j .addError (err )
395400 } else {
@@ -435,6 +440,9 @@ func (j *JSONQ) sortBy(property string, asc bool) *JSONQ {
435440// only return selected properties in result
436441func (j * JSONQ ) only (properties ... string ) interface {} {
437442 result := []interface {}{}
443+ if j .distinctProperty != "" {
444+ j .distinct ()
445+ }
438446 if aa , ok := j .jsonContent .([]interface {}); ok {
439447 for _ , am := range aa {
440448 tmap := map [string ]interface {}{}
@@ -463,6 +471,12 @@ func (j *JSONQ) Only(properties ...string) interface{} {
463471// Pluck build an array of vlaues form a property of a list of objects
464472func (j * JSONQ ) Pluck (property string ) interface {} {
465473 j .prepare ()
474+ if j .distinctProperty != "" {
475+ j .distinct ()
476+ }
477+ if j .limitRecords != 0 {
478+ j .limit ()
479+ }
466480 result := []interface {}{}
467481 if aa , ok := j .jsonContent .([]interface {}); ok {
468482 for _ , am := range aa {
@@ -484,6 +498,7 @@ func (j *JSONQ) reset() *JSONQ {
484498 j .attributes = make ([]string , 0 )
485499 j .queryIndex = 0
486500 j .limitRecords = 0
501+ j .distinctProperty = ""
487502 return j
488503}
489504
@@ -495,6 +510,9 @@ func (j *JSONQ) Reset() *JSONQ {
495510// Get return the result
496511func (j * JSONQ ) Get () interface {} {
497512 j .prepare ()
513+ if j .distinctProperty != "" {
514+ j .distinct ()
515+ }
498516 if j .limitRecords != 0 {
499517 j .limit ()
500518 }
@@ -506,8 +524,11 @@ func (j *JSONQ) Get() interface{} {
506524
507525// First returns the first element of a list
508526func (j * JSONQ ) First () interface {} {
509- res := j .prepare ().jsonContent
510- if arr , ok := res .([]interface {}); ok {
527+ j .prepare ()
528+ if j .distinctProperty != "" {
529+ j .distinct ()
530+ }
531+ if arr , ok := j .jsonContent .([]interface {}); ok {
511532 if len (arr ) > 0 {
512533 return arr [0 ]
513534 }
@@ -517,8 +538,11 @@ func (j *JSONQ) First() interface{} {
517538
518539// Last returns the last element of a list
519540func (j * JSONQ ) Last () interface {} {
520- res := j .prepare ().jsonContent
521- if arr , ok := res .([]interface {}); ok {
541+ j .prepare ()
542+ if j .distinctProperty != "" {
543+ j .distinct ()
544+ }
545+ if arr , ok := j .jsonContent .([]interface {}); ok {
522546 if l := len (arr ); l > 0 {
523547 return arr [l - 1 ]
524548 }
@@ -533,8 +557,11 @@ func (j *JSONQ) Nth(index int) interface{} {
533557 return empty
534558 }
535559
536- res := j .prepare ().jsonContent
537- if arr , ok := res .([]interface {}); ok {
560+ j .prepare ()
561+ if j .distinctProperty != "" {
562+ j .distinct ()
563+ }
564+ if arr , ok := j .jsonContent .([]interface {}); ok {
538565 alen := len (arr )
539566 if alen == 0 {
540567 j .addError (fmt .Errorf ("list is empty" ))
@@ -561,6 +588,9 @@ func (j *JSONQ) Find(path string) interface{} {
561588// This could be a length of list/array/map
562589func (j * JSONQ ) Count () int {
563590 j .prepare ()
591+ if j .distinctProperty != "" {
592+ j .distinct ()
593+ }
564594 lnth := 0
565595 // list of items
566596 if list , ok := j .jsonContent .([]interface {}); ok {
@@ -580,7 +610,7 @@ func (j *JSONQ) Count() int {
580610
581611// Out write the queried data to defined custom type
582612func (j * JSONQ ) Out (v interface {}) {
583- data , err := json .Marshal (j .jsonContent )
613+ data , err := json .Marshal (j .Get () )
584614 if err != nil {
585615 j .addError (err )
586616 return
@@ -626,6 +656,12 @@ func (j *JSONQ) getFloatValFromArray(arr []interface{}, property ...string) []fl
626656// getAggregationValues returns a list of float64 values for aggregation
627657func (j * JSONQ ) getAggregationValues (property ... string ) []float64 {
628658 j .prepare ()
659+ if j .distinctProperty != "" {
660+ j .distinct ()
661+ }
662+ if j .limitRecords != 0 {
663+ j .limit ()
664+ }
629665
630666 ff := []float64 {}
631667 if arr , ok := j .jsonContent .([]interface {}); ok {
0 commit comments