func (j *JSONQ) getAggregationValues(property ...string) []float64 {
	j.prepare()
	if j.distinctProperty != "" {
		j.distinct()
	}
	if j.limitRecords != 0 {
		j.limit()
	}
	var ff []float64
	if arr, ok := j.jsonContent.([]interface{}); ok {
		ff = j.getFloatValFromArray(arr, property...)
	}
	if mv, ok := j.jsonContent.(map[string]interface{}); ok {
		if len(property) == 0 {
			j.addError(fmt.Errorf("property can not be empty for object"))
			return nil
		}
		if fi, ok := mv[property[0]]; ok {
			if flt, ok := fi.(float64); ok {
				ff = append(ff, flt)
			} else {
				j.addError(fmt.Errorf("property %s's value '%v' is not numeric", property[0], fi))
				return nil
			}
		} else {
			j.addError(fmt.Errorf("property '%s' does not exist", property[0]))
			return nil
		}
	}
	return ff
}
getAggregationValues returns a list of float64 values for aggregation
package gojsonq
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
)
func New(options ...OptionFunc) *JSONQ {
	jq := &JSONQ{
		queryMap: defaultQueries(),
		option: option{
			decoder:   &DefaultDecoder{},
			separator: defaultSeparator,
		},
	}
	for _, option := range options {
		if err := option(jq); err != nil {
			jq.addError(err)
		}
	}
	return jq
}
var empty interface{}
const defaultSeparator = "."
type query struct {
	key, operator string
	value         interface{}
}
type JSONQ struct {
	option           option                
	queryMap         map[string]QueryFunc  
	node             string                
	raw              json.RawMessage       
	rootJSONContent  interface{}           
	jsonContent      interface{}           
	queryIndex       int                   
	queries          [][]query             
	attributes       []string              
	offsetRecords    int                   
	limitRecords     int                   
	distinctProperty string                
	errors           []error               
}
func (j *JSONQ) String() string {
	return fmt.Sprintf("\nContent: %s\nQueries:%v\n", string(j.raw), j.queries)
}
func (j *JSONQ) decode() *JSONQ {
	err := j.option.decoder.Decode(j.raw, &j.rootJSONContent)
	if err != nil {
		return j.addError(err)
	}
	j.jsonContent = j.rootJSONContent
	return j
}
func (j *JSONQ) Copy() *JSONQ {
	tmp := *j
	return tmp.reset()
}
func (j *JSONQ) File(filename string) *JSONQ {
	bb, err := ioutil.ReadFile(filename)
	if err != nil {
		return j.addError(err)
	}
	j.raw = bb
	return j.decode()  
}
func (j *JSONQ) JSONString(json string) *JSONQ {
	return j.FromString(json)
}
func (j *JSONQ) FromString(str string) *JSONQ {
	j.raw = []byte(str)
	return j.decode()  
}
func (j *JSONQ) Reader(r io.Reader) *JSONQ {
	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(r)
	if err != nil {
		return j.addError(err)
	}
	j.raw = buf.Bytes()
	buf.Reset()  
	return j.decode()
}
func (j *JSONQ) Error() error {
	errsln := len(j.errors)
	if errsln == 0 {
		return nil
	}
	return j.errors[0]
}
func (j *JSONQ) Errors() []error {
	return j.errors
}
func (j *JSONQ) addError(err error) *JSONQ {
	j.errors = append(j.errors, fmt.Errorf("gojsonq: %v", err))
	return j
}
func (j *JSONQ) Macro(operator string, fn QueryFunc) *JSONQ {
	if _, ok := j.queryMap[operator]; ok {
		j.addError(fmt.Errorf("%s is already registered in query map", operator))
		return j
	}
	j.queryMap[operator] = fn
	return j
}
func (j *JSONQ) From(node string) *JSONQ {
	j.node = node
	v, err := getNestedValue(j.jsonContent, node, j.option.separator)
	if err != nil {
		j.addError(err)
	}
	j.jsonContent = v
	return j
}
func (j *JSONQ) FromInterface(v interface{}) *JSONQ {
	switch data := v.(type) {
	case []interface{}, map[string]interface{}, map[string][]interface{}:
		j.rootJSONContent = data
		j.jsonContent = j.rootJSONContent
	default:
		j.addError(fmt.Errorf("invalid type [%T]", v))
	}
	return j
}
func (j *JSONQ) Select(properties ...string) *JSONQ {
	j.attributes = append(j.attributes, properties...)
	return j
}
func (j *JSONQ) Offset(offset int) *JSONQ {
	j.offsetRecords = offset
	return j
}
func (j *JSONQ) offset() *JSONQ {
	if list, ok := j.jsonContent.([]interface{}); ok {
		if j.offsetRecords < 0 {
			j.addError(fmt.Errorf("%d is invalid offset", j.offsetRecords))
			return j
		}
		if len(list) >= j.offsetRecords {
			j.jsonContent = list[j.offsetRecords:]
		} else {
			j.jsonContent = make([]interface{}, 0)
		}
	}
	return j
}
func (j *JSONQ) Limit(limit int) *JSONQ {
	j.limitRecords = limit
	return j
}
func (j *JSONQ) limit() *JSONQ {
	if list, ok := j.jsonContent.([]interface{}); ok {
		if j.limitRecords <= 0 {
			j.addError(fmt.Errorf("%d is invalid limit", j.limitRecords))
			return j
		}
		if len(list) > j.limitRecords {
			j.jsonContent = list[:j.limitRecords]
		}
	}
	return j
}
func (j *JSONQ) Where(key, cond string, val interface{}) *JSONQ {
	q := query{
		key:      key,
		operator: cond,
		value:    val,
	}
	if j.queryIndex == 0 && len(j.queries) == 0 {
		var qq []query
		qq = append(qq, q)
		j.queries = append(j.queries, qq)
	} else {
		j.queries[j.queryIndex] = append(j.queries[j.queryIndex], q)
	}
	return j
}
func (j *JSONQ) WhereEqual(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorEq, val)
}
func (j *JSONQ) WhereNotEqual(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorNotEq, val)
}
func (j *JSONQ) WhereNil(key string) *JSONQ {
	return j.Where(key, operatorEq, nil)
}
func (j *JSONQ) WhereNotNil(key string) *JSONQ {
	return j.Where(key, operatorNotEq, nil)
}
func (j *JSONQ) WhereIn(key string, val interface{}) *JSONQ {
	j.Where(key, operatorIn, val)
	return j
}
func (j *JSONQ) WhereNotIn(key string, val interface{}) *JSONQ {
	j.Where(key, operatorNotIn, val)
	return j
}
func (j *JSONQ) OrWhere(key, cond string, val interface{}) *JSONQ {
	j.queryIndex++
	var qq []query
	qq = append(qq, query{
		key:      key,
		operator: cond,
		value:    val,
	})
	j.queries = append(j.queries, qq)
	return j
}
func (j *JSONQ) WhereStartsWith(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorStartsWith, val)
}
func (j *JSONQ) WhereEndsWith(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorEndsWith, val)
}
func (j *JSONQ) WhereContains(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorContains, val)
}
func (j *JSONQ) WhereStrictContains(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorStrictContains, val)
}
func (j *JSONQ) WhereLenEqual(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorLenEq, val)
}
func (j *JSONQ) WhereLenNotEqual(key string, val interface{}) *JSONQ {
	return j.Where(key, operatorLenNotEq, val)
}
func (j *JSONQ) findInArray(aa []interface{}) []interface{} {
	result := make([]interface{}, 0)
	for _, a := range aa {
		if m, ok := a.(map[string]interface{}); ok {
			result = append(result, j.findInMap(m)...)
		}
	}
	return result
}
func (j *JSONQ) findInMap(vm map[string]interface{}) []interface{} {
	result := make([]interface{}, 0)
	orPassed := false
	for _, qList := range j.queries {
		andPassed := true
		for _, q := range qList {
			cf, ok := j.queryMap[q.operator]
			if !ok {
				j.addError(fmt.Errorf("invalid operator %s", q.operator))
				return result
			}
			nv, errnv := getNestedValue(vm, q.key, j.option.separator)
			if errnv != nil {
				j.addError(errnv)
				andPassed = false
			} else {
				qb, err := cf(nv, q.value)
				if err != nil {
					j.addError(err)
				}
				andPassed = andPassed && qb
			}
		}
		orPassed = orPassed || andPassed
	}
	if orPassed {
		result = append(result, vm)
	}
	return result
}
func (j *JSONQ) processQuery() *JSONQ {
	if aa, ok := j.jsonContent.([]interface{}); ok {
		j.jsonContent = j.findInArray(aa)
	}
	return j
}
func (j *JSONQ) prepare() *JSONQ {
	if len(j.queries) > 0 {
		j.processQuery()
	}
	if j.distinctProperty != "" {
		j.distinct()
	}
	if len(j.attributes) > 0 {
		j.jsonContent = j.only(j.attributes...)
	}
	j.queryIndex = 0
	return j
}
func (j *JSONQ) GroupBy(property string) *JSONQ {
	j.prepare()
	dt := map[string][]interface{}{}
	if aa, ok := j.jsonContent.([]interface{}); ok {
		for _, a := range aa {
			if vm, ok := a.(map[string]interface{}); ok {
				v, err := getNestedValue(vm, property, j.option.separator)
				if err != nil {
					j.addError(err)
				} else {
					dt[toString(v)] = append(dt[toString(v)], vm)
				}
			}
		}
	}
	j.jsonContent = dt
	return j
}
func (j *JSONQ) Sort(order ...string) *JSONQ {
	j.prepare()
	asc := true
	if len(order) > 1 {
		return j.addError(fmt.Errorf("sort accepts only one argument asc/desc"))
	}
	if len(order) > 0 && order[0] == "desc" {
		asc = false
	}
	if arr, ok := j.jsonContent.([]interface{}); ok {
		j.jsonContent = sortList(arr, asc)
	}
	return j
}
func (j *JSONQ) SortBy(order ...string) *JSONQ {
	j.prepare()
	asc := true
	if len(order) == 0 {
		return j.addError(fmt.Errorf("provide at least one argument as property name"))
	}
	if len(order) > 2 {
		return j.addError(fmt.Errorf("sort accepts only two arguments. first argument property name and second argument asc/desc"))
	}
	if len(order) > 1 && order[1] == "desc" {
		asc = false
	}
	return j.sortBy(order[0], asc)
}
func (j *JSONQ) Distinct(property string) *JSONQ {
	j.distinctProperty = property
	return j
}
func (j *JSONQ) distinct() *JSONQ {
	m := map[string]bool{}
	var dt = make([]interface{}, 0)
	if aa, ok := j.jsonContent.([]interface{}); ok {
		for _, a := range aa {
			if vm, ok := a.(map[string]interface{}); ok {
				v, err := getNestedValue(vm, j.distinctProperty, j.option.separator)
				if err != nil {
					j.addError(err)
				} else {
					if _, exist := m[toString(v)]; !exist {
						dt = append(dt, vm)
						m[toString(v)] = true
					}
				}
			}
		}
	}
	j.jsonContent = dt
	return j
}
func (j *JSONQ) sortBy(property string, asc bool) *JSONQ {
	sortResult, ok := j.jsonContent.([]interface{})
	if !ok {
		return j
	}
	if len(sortResult) == 0 {
		return j
	}
	sm := &sortMap{}
	sm.separator = j.option.separator
	sm.key = property
	if !asc {
		sm.desc = true
	}
	sm.Sort(sortResult)
	for _, e := range sm.errs {
		j.addError(e)
	}
	j.jsonContent = sortResult
	return j
}
func (j *JSONQ) only(properties ...string) interface{} {
	var result = make([]interface{}, 0)
	if aa, ok := j.jsonContent.([]interface{}); ok {
		for _, am := range aa {
			tmap := map[string]interface{}{}
			for _, prop := range properties {
				node, alias := makeAlias(prop, j.option.separator)
				rv, errV := getNestedValue(am, node, j.option.separator)
				if errV != nil {
					j.addError(errV)
					continue
				}
				tmap[alias] = rv
			}
			if len(tmap) > 0 {
				result = append(result, tmap)
			}
		}
	}
	return result
}
func (j *JSONQ) Only(properties ...string) interface{} {
	return j.prepare().only(properties...)
}
func (j *JSONQ) OnlyR(properties ...string) (*Result, error) {
	v := j.Only(properties...)
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) Pluck(property string) interface{} {
	j.prepare()
	if j.distinctProperty != "" {
		j.distinct()
	}
	if j.limitRecords != 0 {
		j.limit()
	}
	var result = make([]interface{}, 0)
	if aa, ok := j.jsonContent.([]interface{}); ok {
		for _, am := range aa {
			if mv, ok := am.(map[string]interface{}); ok {
				if v, ok := mv[property]; ok {
					result = append(result, v)
				}
			}
		}
	}
	return result
}
func (j *JSONQ) PluckR(property string) (*Result, error) {
	v := j.Pluck(property)
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) reset() *JSONQ {
	j.raw = nil
	j.jsonContent = j.rootJSONContent
	j.node = ""
	j.queries = make([][]query, 0)
	j.attributes = make([]string, 0)
	j.queryIndex = 0
	j.offsetRecords = 0
	j.limitRecords = 0
	j.distinctProperty = ""
	j.errors = make([]error, 0)
	return j
}
func (j *JSONQ) Reset() *JSONQ {
	return j.reset()
}
func (j *JSONQ) Get() interface{} {
	j.prepare()
	if j.offsetRecords != 0 {
		j.offset()
	}
	if j.limitRecords != 0 {
		j.limit()
	}
	return j.jsonContent
}
func (j *JSONQ) GetR() (*Result, error) {
	v := j.Get()
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) First() interface{} {
	j.prepare()
	if arr, ok := j.jsonContent.([]interface{}); ok {
		if len(arr) > 0 {
			return arr[0]
		}
	}
	return empty
}
func (j *JSONQ) FirstR() (*Result, error) {
	v := j.First()
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) Last() interface{} {
	j.prepare()
	if arr, ok := j.jsonContent.([]interface{}); ok {
		if l := len(arr); l > 0 {
			return arr[l-1]
		}
	}
	return empty
}
func (j *JSONQ) LastR() (*Result, error) {
	v := j.Last()
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) Nth(index int) interface{} {
	if index == 0 {
		j.addError(fmt.Errorf("index is not zero based"))
		return empty
	}
	j.prepare()
	if arr, ok := j.jsonContent.([]interface{}); ok {
		alen := len(arr)
		if alen == 0 {
			j.addError(fmt.Errorf("list is empty"))
			return empty
		}
		if abs(index) > alen {
			j.addError(fmt.Errorf("index out of range"))
			return empty
		}
		if index > 0 {
			return arr[index-1]
		}
		return arr[alen+index]
	}
	return empty
}
func (j *JSONQ) NthR(index int) (*Result, error) {
	v := j.Nth(index)
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) Find(path string) interface{} {
	return j.From(path).Get()
}
func (j *JSONQ) FindR(path string) (*Result, error) {
	v := j.Find(path)
	if err := j.Error(); err != nil {
		return nil, err
	}
	return NewResult(v), nil
}
func (j *JSONQ) Count() int {
	j.prepare()
	var lnth int
	if list, ok := j.jsonContent.([]interface{}); ok {
		lnth = len(list)
	}
	if m, ok := j.jsonContent.(map[string]interface{}); ok {
		lnth = len(m)
	}
	if m, ok := j.jsonContent.(map[string][]interface{}); ok {
		lnth = len(m)
	}
	return lnth
}
func (j *JSONQ) Out(v interface{}) {
	data, err := json.Marshal(j.Get())
	if err != nil {
		j.addError(err)
		return
	}
	if err := json.Unmarshal(data, &v); err != nil {
		j.addError(err)
	}
}
func (j *JSONQ) Writer(w io.Writer) {
	err := json.NewEncoder(w).Encode(j.Get())
	if err != nil {
		j.addError(err)
		return
	}
}
func (j *JSONQ) More() *JSONQ {
	j.raw = nil
	j.rootJSONContent = j.Get()
	j.node = ""
	j.queries = make([][]query, 0)
	j.attributes = make([]string, 0)
	j.queryIndex = 0
	j.limitRecords = 0
	j.distinctProperty = ""
	return j
}
func (j *JSONQ) getFloatValFromArray(arr []interface{}, property ...string) []float64 {
	var ff []float64
	for _, a := range arr {
		if av, ok := a.(float64); ok {
			if len(property) > 0 {
				j.addError(fmt.Errorf("unnecessary property name for array"))
				return nil
			}
			ff = append(ff, av)
		}
		if mv, ok := a.(map[string]interface{}); ok {
			if len(property) == 0 {
				j.addError(fmt.Errorf("property name can not be empty for object"))
				return nil
			}
			if fi, ok := mv[property[0]]; ok {
				if flt, ok := fi.(float64); ok {
					ff = append(ff, flt)
				} else {
					j.addError(fmt.Errorf("property %s's value '%v' is not numeric", property[0], fi))
					return nil
				}
			} else {
				j.addError(fmt.Errorf("property '%s' does not exist", property[0]))
				return nil
			}
		}
	}
	return ff
}