package coperator import ( "errors" "reflect" ) /* Compare 比较两个任意类型的值 参数: a: 第一个比较值 b: 第二个比较值 返回值: int: 比较结果 (-1:a < b, 0:a == b, 1:a > b) error: 类型不匹配或不可比较时返回错误 */ func compare(a, b interface{}) (int, error) { // 快速返回:如果值完全相等直接返回0 // 获取类型信息并验证类型一致性 atype := reflect.TypeOf(a) btype := reflect.TypeOf(b) if atype != btype { return 0, errors.New("types are not equal: " + atype.String() + " != " + btype.String()) } // 验证类型是否可比较 if !atype.Comparable() { return 0, errors.New("types are not comparable: " + atype.String()) } if reflect.DeepEqual(a, b) { return 0, nil } // 处理不同类型的基础类型比较 switch atype.Kind() { // 处理有符号整数类型比较 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: av := reflect.ValueOf(a).Int() bv := reflect.ValueOf(b).Int() if av < bv { return -1, nil } if av > bv { return 1, nil } return 0, nil // 处理无符号整数类型比较 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: av := reflect.ValueOf(a).Uint() bv := reflect.ValueOf(b).Uint() if av < bv { return -1, nil } if av > bv { return 1, nil } return 0, nil // 处理浮点数类型比较 case reflect.Float32, reflect.Float64: av := reflect.ValueOf(a).Float() bv := reflect.ValueOf(b).Float() if av < bv { return -1, nil } if av > bv { return 1, nil } return 0, nil // 处理字符串类型比较 case reflect.String: av := reflect.ValueOf(a).String() bv := reflect.ValueOf(b).String() if av < bv { return -1, nil } if av > bv { return 1, nil } return 0, nil // 布尔类型特殊处理 case reflect.Bool: return 0, errors.New("cannot compare boolean values") // 默认不支持的类型 default: return 0, errors.New("unsupported type for comparison: " + atype.String()) } } func comparOp(doc *Document, key string, value interface{}) (int, error) { v := doc.Get(key) if v == nil { return 0, nil } ret, err := compare(v, value) if err != nil { return 0, err } return ret, nil } func operatorGt(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v > 0, nil } func operatorGe(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v >= 0, nil } func operatorLt(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v < 0, nil } func operatorLe(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v <= 0, nil } func operatorEq(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v == 0, nil } func operatorNe(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { v, e := comparOp(doc, key, value) if e != nil { return false, e } return v != 0, nil } func operatorIn(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { if value == nil { return false, nil } slice, ok := value.([]interface{}) if !ok { return false, errors.New("value for $in operator must be a slice") } if len(slice) == 0 { return false, nil } for _, v := range slice { cmp, err := compare(doc.Get(key), v) if err != nil { return false, err } if cmp == 0 { return true, nil } } return false, nil } func operatorNotIn(doc *Document, filter Filter, key string, value interface{}) (ret bool, err error) { lret, err := operatorIn(doc, filter, key, value) if err != nil { return false, err } return !lret, nil }