package engine import ( "strings" "git.kingecg.top/kingecg/gomog/pkg/types" ) // MatchFilter 匹配过滤器 func MatchFilter(doc map[string]interface{}, filter types.Filter) bool { if filter == nil || len(filter) == 0 { return true } for key, condition := range filter { switch key { case "$and": if !handleAnd(doc, condition) { return false } case "$or": if !handleOr(doc, condition) { return false } case "$nor": if !handleNor(doc, condition) { return false } case "$not": if !handleNot(doc, condition) { return false } default: if !matchField(doc, key, condition) { return false } } } return true } // handleAnd 处理 $and 操作符 func handleAnd(doc map[string]interface{}, condition interface{}) bool { andConditions, ok := condition.([]interface{}) if !ok { return false } for _, cond := range andConditions { if condMap, ok := cond.(map[string]interface{}); ok { if !MatchFilter(doc, condMap) { return false } } } return true } // handleOr 处理 $or 操作符 func handleOr(doc map[string]interface{}, condition interface{}) bool { orConditions, ok := condition.([]interface{}) if !ok { return false } for _, cond := range orConditions { if condMap, ok := cond.(map[string]interface{}); ok { if MatchFilter(doc, condMap) { return true } } } return false } // handleNor 处理 $nor 操作符 func handleNor(doc map[string]interface{}, condition interface{}) bool { orConditions, ok := condition.([]interface{}) if !ok { return false } for _, cond := range orConditions { if condMap, ok := cond.(map[string]interface{}); ok { if MatchFilter(doc, condMap) { return false } } } return true } // handleNot 处理 $not 操作符 func handleNot(doc map[string]interface{}, condition interface{}) bool { if condMap, ok := condition.(map[string]interface{}); ok { return !MatchFilter(doc, condMap) } return true } // matchField 匹配字段 func matchField(doc map[string]interface{}, key string, condition interface{}) bool { value := getNestedValue(doc, key) // 处理操作符条件 if condMap, ok := condition.(map[string]interface{}); ok { return evaluateOperators(value, condMap) } // 简单相等比较 return compareEq(value, condition) } // getNestedValue 获取嵌套字段值(支持 "a.b.c" 格式) func getNestedValue(doc map[string]interface{}, key string) interface{} { parts := strings.Split(key, ".") var current interface{} = doc for _, part := range parts { if m, ok := current.(map[string]interface{}); ok { current = m[part] } else { return nil } } return current } // evaluateOperators 评估操作符 func evaluateOperators(value interface{}, operators map[string]interface{}) bool { for op, operand := range operators { switch op { case "$eq": if !compareEq(value, operand) { return false } case "$ne": if compareEq(value, operand) { return false } case "$gt": if !compareGt(value, operand) { return false } case "$gte": if !compareGte(value, operand) { return false } case "$lt": if !compareLt(value, operand) { return false } case "$lte": if !compareLte(value, operand) { return false } case "$in": if !compareIn(value, operand) { return false } case "$nin": if compareIn(value, operand) { return false } case "$regex": if !compareRegex(value, operand) { return false } case "$exists": exists := value != nil if operandBool, ok := operand.(bool); ok { if exists != operandBool { return false } } case "$type": if !compareType(value, operand) { return false } case "$all": if !compareAll(value, operand) { return false } case "$elemMatch": if !compareElemMatch(value, operand) { return false } case "$size": if !compareSize(value, operand) { return false } default: // 未知操作符,跳过 } } return true }