// Range returns one or more records by the specified index within the specified range func (n *node) Range(fieldName string, min, max, to interface{}, options ...func(*index.Options)) error { sink, err := newListSink(n, to) if err != nil { return err } bucketName := sink.bucketName() if bucketName == "" { return ErrNoName } ref := reflect.Indirect(reflect.New(sink.elemType)) cfg, err := extractSingleField(&ref, fieldName) if err != nil { return err } opts := index.NewOptions() for _, fn := range options { fn(opts) } field, ok := cfg.Fields[fieldName] if !ok || (!field.IsID && field.Index == "") { sink.limit = opts.Limit sink.skip = opts.Skip query := newQuery(n, q.And(q.Gte(fieldName, min), q.Lte(fieldName, max))) if opts.Reverse { query.Reverse() } err = n.readTx(func(tx *bolt.Tx) error { return query.query(tx, sink) }) if err != nil { return err } return sink.flush() } mn, err := toBytes(min, n.s.codec) if err != nil { return err } mx, err := toBytes(max, n.s.codec) if err != nil { return err } return n.readTx(func(tx *bolt.Tx) error { return n.rnge(tx, bucketName, fieldName, cfg, sink, mn, mx, opts) }) }
// Select a list of records that match a list of matchers. Doesn't use indexes. func (n *node) Select(matchers ...q.Matcher) Query { tree := q.And(matchers...) return newQuery(n, tree) }