用户定义函数 #

一、函数概述 #

1.1 什么是UDF #

text
用户定义函数(UDF)特点:
├── 封装可重用逻辑
├── 支持参数传递
├── 可在查询中调用
├── 支持递归
└── 可设置访问权限

1.2 函数优势 #

text
使用函数的好处:
├── 代码复用
├── 简化复杂查询
├── 统一业务逻辑
├── 提高可维护性
└── 权限控制

二、创建函数 #

2.1 基本创建 #

javascript
// 创建简单函数
CreateFunction({
  name: "hello",
  body: Query(
    Lambda("name",
      Concat(["Hello, ", Var("name"), "!"])
    )
  )
})

// 调用函数
Call(Function("hello"), "World")
// 结果: "Hello, World!"

2.2 带角色的函数 #

javascript
// 创建带权限的函数
CreateFunction({
  name: "create_user",
  role: Role("server"),
  body: Query(
    Lambda(["name", "email"],
      Create(Collection("users"), {
        data: {
          name: Var("name"),
          email: Var("email"),
          createdAt: Now()
        }
      })
    )
  )
})

2.3 函数信息 #

javascript
// 获取函数信息
Get(Function("hello"))

// 列出所有函数
Paginate(Functions())

// 检查函数是否存在
Exists(Function("hello"))

三、参数处理 #

3.1 单参数 #

javascript
// 单参数函数
CreateFunction({
  name: "double",
  body: Query(
    Lambda("x",
      Multiply(Var("x"), 2)
    )
  )
})

// 调用
Call(Function("double"), 5)
// 结果: 10

3.2 多参数 #

javascript
// 多参数函数
CreateFunction({
  name: "add",
  body: Query(
    Lambda(["x", "y"],
      Add(Var("x"), Var("y"))
    )
  )
})

// 调用
Call(Function("add"), [3, 4])
// 结果: 7

3.3 对象参数 #

javascript
// 对象参数函数
CreateFunction({
  name: "create_product",
  body: Query(
    Lambda("data",
      Create(Collection("products"), {
        data: Merge(Var("data"), {
          createdAt: Now()
        })
      })
    )
  )
})

// 调用
Call(Function("create_product"), {
  name: "iPhone",
  price: 999,
  category: "electronics"
})

3.4 默认参数 #

javascript
// 带默认值的参数
CreateFunction({
  name: "greet",
  body: Query(
    Lambda("name",
      Concat([
        "Hello, ",
        If(
          Equals(Var("name"), null),
          "Guest",
          Var("name")
        ),
        "!"
      ])
    )
  )
})

四、返回值 #

4.1 返回简单值 #

javascript
// 返回字符串
CreateFunction({
  name: "get_greeting",
  body: Query(
    Lambda("name",
      Concat(["Hello, ", Var("name")])
    )
  )
})

// 返回数字
CreateFunction({
  name: "calculate_total",
  body: Query(
    Lambda(["price", "quantity"],
      Multiply(Var("price"), Var("quantity"))
    )
  )
})

4.2 返回文档 #

javascript
// 返回创建的文档
CreateFunction({
  name: "create_order",
  body: Query(
    Lambda(["userId", "items"],
      Create(Collection("orders"), {
        data: {
          user: Ref(Collection("users"), Var("userId")),
          items: Var("items"),
          status: "pending",
          createdAt: Now()
        }
      })
    )
  )
})

4.3 返回复杂对象 #

javascript
// 返回复杂结果
CreateFunction({
  name: "get_user_stats",
  body: Query(
    Lambda("userId",
      Let(
        {
          userRef: Ref(Collection("users"), Var("userId")),
          user: Get(Var("userRef")),
          orderCount: Count(Match(Index("orders_by_user"), Var("userRef"))),
          totalSpent: Reduce(
            Map(
              Paginate(Match(Index("orders_by_user"), Var("userRef"))),
              Lambda("ref",
                Select(["data", "total"], Get(Var("ref")))
              )
            ),
            Lambda(["acc", "val"], Add(Var("acc"), Var("val"))),
            0
          )
        },
        {
          user: {
            name: Select(["data", "name"], Var("user")),
            email: Select(["data", "email"], Var("user"))
          },
          statistics: {
            orderCount: Var("orderCount"),
            totalSpent: Var("totalSpent")
          }
        }
      )
    )
  )
})

五、递归函数 #

5.1 基本递归 #

javascript
// 阶乘函数
CreateFunction({
  name: "factorial",
  body: Query(
    Lambda("n",
      If(
        LTE(Var("n"), 1),
        1,
        Multiply(
          Var("n"),
          Call(Function("factorial"), Subtract(Var("n"), 1))
        )
      )
    )
  )
})

// 调用
Call(Function("factorial"), 5)
// 结果: 120

5.2 斐波那契 #

javascript
// 斐波那契数列
CreateFunction({
  name: "fibonacci",
  body: Query(
    Lambda("n",
      If(
        LTE(Var("n"), 1),
        Var("n"),
        Add(
          Call(Function("fibonacci"), Subtract(Var("n"), 1)),
          Call(Function("fibonacci"), Subtract(Var("n"), 2))
        )
      )
    )
  )
})

5.3 尾递归优化 #

javascript
// 尾递归阶乘
CreateFunction({
  name: "factorial_tail",
  body: Query(
    Lambda(["n", "acc"],
      If(
        LTE(Var("n"), 1),
        Var("acc"),
        Call(
          Function("factorial_tail"),
          [Subtract(Var("n"), 1), Multiply(Var("n"), Var("acc"))]
        )
      )
    )
  )
})

// 包装函数
CreateFunction({
  name: "factorial",
  body: Query(
    Lambda("n",
      Call(Function("factorial_tail"), [Var("n"), 1])
    )
  )
})

六、函数组合 #

6.1 调用其他函数 #

javascript
// 创建辅助函数
CreateFunction({
  name: "calculate_tax",
  body: Query(
    Lambda("amount",
      Multiply(Var("amount"), 0.1)
    )
  )
})

// 创建主函数
CreateFunction({
  name: "calculate_total_with_tax",
  body: Query(
    Lambda("amount",
      Let(
        {
          tax: Call(Function("calculate_tax"), Var("amount"))
        },
        Add(Var("amount"), Var("tax"))
      )
    )
  )
})

6.2 高阶函数 #

javascript
// 创建高阶函数
CreateFunction({
  name: "apply_to_all",
  body: Query(
    Lambda(["items", "fn"],
      Map(
        Var("items"),
        Lambda("item",
          Call(Var("fn"), Var("item"))
        )
      )
    )
  )
})

七、实际应用示例 #

7.1 用户注册函数 #

javascript
// 完整的用户注册函数
CreateFunction({
  name: "register_user",
  role: Role("server"),
  body: Query(
    Lambda(["name", "email", "password"],
      If(
        Exists(Match(Index("users_by_email"), Var("email"))),
        Abort("Email already registered"),
        Do(
          Let(
            {
              user: Create(Collection("users"), {
                data: {
                  name: Var("name"),
                  email: Var("email"),
                  status: "active",
                  createdAt: Now()
                }
              }),
              userRef: Select(["ref"], Var("user"))
            },
            Do(
              // 创建凭证
              Create(Collection("credentials"), {
                data: {
                  user: Var("userRef"),
                  password: Var("password")
                }
              }),
              // 创建默认配置
              Create(Collection("user_settings"), {
                data: {
                  user: Var("userRef"),
                  notifications: true,
                  theme: "light"
                }
              }),
              // 返回用户
              Var("user")
            )
          )
        )
      )
    )
  )
})

7.2 订单处理函数 #

javascript
// 订单处理函数
CreateFunction({
  name: "process_order",
  role: Role("server"),
  body: Query(
    Lambda("orderId",
      Let(
        {
          orderRef: Ref(Collection("orders"), Var("orderId")),
          order: Get(Var("orderRef"))
        },
        If(
          Not(Equals(Select(["data", "status"], Var("order")), "pending")),
          Abort("Order is not in pending status"),
          Let(
            {
              items: Select(["data", "items"], Var("order")),
              userId: Select(["data", "userId"], Var("order"))
            },
            Do(
              // 验证库存
              Foreach(
                Var("items"),
                Lambda("item",
                  Let(
                    {
                      productRef: Ref(Collection("products"), Select("productId", Var("item"))),
                      quantity: Select("quantity", Var("item")),
                      product: Get(Var("productRef")),
                      stock: Select(["data", "stock"], Var("product"))
                    },
                    If(
                      LT(Var("stock"), Var("quantity")),
                      Abort(Concat(["Insufficient stock: ", Select("productId", Var("item"))])),
                      Update(Var("productRef"), {
                        data: { stock: Subtract(Var("stock"), Var("quantity")) }
                      })
                    )
                  )
                )
              ),
              // 更新订单状态
              Update(Var("orderRef"), {
                data: {
                  status: "processing",
                  processedAt: Now()
                }
              })
            )
          )
        )
      )
    )
  )
})

7.3 搜索函数 #

javascript
// 产品搜索函数
CreateFunction({
  name: "search_products",
  body: Query(
    Lambda(["query", "filters"],
      Let(
        {
          searchTerm: LowerCase(Var("query")),
          minPrice: Select("minPrice", Var("filters"), 0),
          maxPrice: Select("maxPrice", Var("filters"), 999999),
          category: Select("category", Var("filters"), null)
        },
        Filter(
          Paginate(
            If(
              Equals(Var("category"), null),
              Documents(Collection("products")),
              Match(Index("products_by_category"), Var("category"))
            )
          ),
          Lambda("ref",
            Let(
              { doc: Get(Var("ref")) },
              And(
                // 价格范围
                GTE(Select(["data", "price"], Var("doc")), Var("minPrice")),
                LTE(Select(["data", "price"], Var("doc")), Var("maxPrice")),
                // 搜索词
                ContainsStr(
                  LowerCase(Concat([
                    Select(["data", "name"], Var("doc"), ""),
                    " ",
                    Select(["data", "description"], Var("doc"), "")
                  ])),
                  Var("searchTerm")
                )
              )
            )
          )
        )
      )
    )
  )
})

八、函数管理 #

8.1 更新函数 #

javascript
// 更新函数
Update(Function("hello"), {
  body: Query(
    Lambda("name",
      Concat(["Hello, ", Var("name"), "! Welcome!"])
    )
  )
})

8.2 删除函数 #

javascript
// 删除函数
Delete(Function("old_function"))

8.3 函数权限 #

javascript
// 创建带权限的函数
CreateFunction({
  name: "admin_only_function",
  role: Role("admin"),
  body: Query(
    Lambda("data",
      // 管理员操作
    )
  )
})

九、最佳实践 #

9.1 命名规范 #

text
函数命名建议:
├── 使用动词开头
├── 描述功能
├── 使用下划线分隔
└── 示例:create_user, get_user_stats

9.2 参数验证 #

javascript
// 验证参数
CreateFunction({
  name: "safe_divide",
  body: Query(
    Lambda(["x", "y"],
      If(
        Equals(Var("y"), 0),
        Abort("Division by zero"),
        Divide(Var("x"), Var("y"))
      )
    )
  )
})

9.3 文档注释 #

javascript
// 创建带注释的函数
CreateFunction({
  name: "calculate_discount",
  body: Query(
    Lambda(["price", "discountPercent"],
      // 验证参数
      If(
        Or(
          Not(IsNumber(Var("price"))),
          Not(IsNumber(Var("discountPercent")))
        ),
        Abort("Invalid parameters"),
        If(
          Or(
            LT(Var("price"), 0),
            LT(Var("discountPercent"), 0),
            GT(Var("discountPercent"), 100)
          ),
          Abort("Invalid parameter values"),
          Subtract(
            Var("price"),
            Multiply(Var("price"), Divide(Var("discountPercent"), 100))
          )
        )
      )
    )
  )
})

十、总结 #

用户定义函数要点:

特性 说明
CreateFunction 创建函数
Call 调用函数
Lambda 参数定义
Query 包装函数体
role 权限设置

下一步,让我们学习访问控制!

最后更新:2026-03-27