@@ -2637,6 +2637,188 @@ func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse {
26372637
26382638//------------------------------------------------------------------------------
26392639
2640+ // GeoSearchQuery is used for GEOSearch/GEOSearchStore command query.
2641+ type GeoSearchQuery struct {
2642+ Member string
2643+
2644+ // Latitude and Longitude when using FromLonLat option.
2645+ Longitude float64
2646+ Latitude float64
2647+
2648+ // Distance and unit when using ByRadius option.
2649+ // Can use m, km, ft, or mi. Default is km.
2650+ Radius float64
2651+ RadiusUnit string
2652+
2653+ // Height, width and unit when using ByBox option.
2654+ // Can be m, km, ft, or mi. Default is km.
2655+ BoxWidth float64
2656+ BoxHeight float64
2657+ BoxUnit string
2658+
2659+ // Can be ASC or DESC. Default is no sort order.
2660+ Sort string
2661+ Count int
2662+ CountAny bool
2663+ }
2664+
2665+ type GeoSearchLocationQuery struct {
2666+ GeoSearchQuery
2667+
2668+ WithCoord bool
2669+ WithDist bool
2670+ WithHash bool
2671+ }
2672+
2673+ type GeoSearchStoreQuery struct {
2674+ GeoSearchQuery
2675+
2676+ // When using the StoreDist option, the command stores the items in a
2677+ // sorted set populated with their distance from the center of the circle or box,
2678+ // as a floating-point number, in the same unit specified for that shape.
2679+ StoreDist bool
2680+ }
2681+
2682+ func geoSearchLocationArgs (q * GeoSearchLocationQuery , args []interface {}) []interface {} {
2683+ args = geoSearchArgs (& q .GeoSearchQuery , args )
2684+
2685+ if q .WithCoord {
2686+ args = append (args , "withcoord" )
2687+ }
2688+ if q .WithDist {
2689+ args = append (args , "withdist" )
2690+ }
2691+ if q .WithHash {
2692+ args = append (args , "withhash" )
2693+ }
2694+
2695+ return args
2696+ }
2697+
2698+ func geoSearchArgs (q * GeoSearchQuery , args []interface {}) []interface {} {
2699+ if q .Member != "" {
2700+ args = append (args , "frommember" , q .Member )
2701+ } else {
2702+ args = append (args , "fromlonlat" , q .Longitude , q .Latitude )
2703+ }
2704+
2705+ if q .Radius > 0 {
2706+ if q .RadiusUnit == "" {
2707+ q .RadiusUnit = "km"
2708+ }
2709+ args = append (args , "byradius" , q .Radius , q .RadiusUnit )
2710+ } else {
2711+ if q .BoxUnit == "" {
2712+ q .BoxUnit = "km"
2713+ }
2714+ args = append (args , "bybox" , q .BoxWidth , q .BoxHeight , q .BoxUnit )
2715+ }
2716+
2717+ if q .Sort != "" {
2718+ args = append (args , q .Sort )
2719+ }
2720+
2721+ if q .Count > 0 {
2722+ args = append (args , "count" , q .Count )
2723+ if q .CountAny {
2724+ args = append (args , "any" )
2725+ }
2726+ }
2727+
2728+ return args
2729+ }
2730+
2731+ type GeoSearchLocationCmd struct {
2732+ baseCmd
2733+
2734+ opt * GeoSearchLocationQuery
2735+ val []GeoLocation
2736+ }
2737+
2738+ var _ Cmder = (* GeoSearchLocationCmd )(nil )
2739+
2740+ func NewGeoSearchLocationCmd (
2741+ ctx context.Context , opt * GeoSearchLocationQuery , args ... interface {},
2742+ ) * GeoSearchLocationCmd {
2743+ return & GeoSearchLocationCmd {
2744+ baseCmd : baseCmd {
2745+ ctx : ctx ,
2746+ args : args ,
2747+ },
2748+ opt : opt ,
2749+ }
2750+ }
2751+
2752+ func (cmd * GeoSearchLocationCmd ) Val () []GeoLocation {
2753+ return cmd .val
2754+ }
2755+
2756+ func (cmd * GeoSearchLocationCmd ) Result () ([]GeoLocation , error ) {
2757+ return cmd .val , cmd .err
2758+ }
2759+
2760+ func (cmd * GeoSearchLocationCmd ) String () string {
2761+ return cmdString (cmd , cmd .val )
2762+ }
2763+
2764+ func (cmd * GeoSearchLocationCmd ) readReply (rd * proto.Reader ) error {
2765+ n , err := rd .ReadArrayLen ()
2766+ if err != nil {
2767+ return err
2768+ }
2769+
2770+ cmd .val = make ([]GeoLocation , n )
2771+ for i := 0 ; i < n ; i ++ {
2772+ _ , err = rd .ReadArrayLen ()
2773+ if err != nil {
2774+ return err
2775+ }
2776+
2777+ var loc GeoLocation
2778+
2779+ loc .Name , err = rd .ReadString ()
2780+ if err != nil {
2781+ return err
2782+ }
2783+ if cmd .opt .WithDist {
2784+ loc .Dist , err = rd .ReadFloatReply ()
2785+ if err != nil {
2786+ return err
2787+ }
2788+ }
2789+ if cmd .opt .WithHash {
2790+ loc .GeoHash , err = rd .ReadIntReply ()
2791+ if err != nil {
2792+ return err
2793+ }
2794+ }
2795+ if cmd .opt .WithCoord {
2796+ nn , err := rd .ReadArrayLen ()
2797+ if err != nil {
2798+ return err
2799+ }
2800+ if nn != 2 {
2801+ return fmt .Errorf ("got %d coordinates, expected 2" , nn )
2802+ }
2803+
2804+ loc .Longitude , err = rd .ReadFloatReply ()
2805+ if err != nil {
2806+ return err
2807+ }
2808+ loc .Latitude , err = rd .ReadFloatReply ()
2809+ if err != nil {
2810+ return err
2811+ }
2812+ }
2813+
2814+ cmd .val [i ] = loc
2815+ }
2816+
2817+ return nil
2818+ }
2819+
2820+ //------------------------------------------------------------------------------
2821+
26402822type GeoPos struct {
26412823 Longitude , Latitude float64
26422824}
0 commit comments