索引查询 #

一、索引查询基础 #

1.1 索引查询流程 #

text
索引查询流程:
├── 1. 创建索引
├── 2. 使用Match查询
├── 3. 获取结果
└── 4. 处理数据

1.2 基本索引查询 #

javascript
// 创建索引
CreateIndex({
  name: "users_by_email",
  source: Collection("users"),
  terms: [
    { field: ["data", "email"] }
  ]
})

// 查询
Get(Match(Index("users_by_email"), "tom@example.com"))

二、复合索引查询 #

2.1 创建复合索引 #

javascript
// 多字段复合索引
CreateIndex({
  name: "orders_by_user_status_date",
  source: Collection("orders"),
  terms: [
    { field: ["data", "userId"] },
    { field: ["data", "status"] }
  ],
  values: [
    { field: ["data", "createdAt"], order: "desc" },
    { field: ["ref"] }
  ]
})

2.2 使用复合索引 #

javascript
// 完整匹配查询
Match(
  Index("orders_by_user_status_date"),
  "user_001",
  "pending"
)

// 分页查询
Paginate(
  Match(
    Index("orders_by_user_status_date"),
    "user_001",
    "pending"
  ),
  { size: 20 }
)

2.3 部分匹配 #

javascript
// 只使用第一个term
// 需要创建单独的索引
CreateIndex({
  name: "orders_by_user",
  source: Collection("orders"),
  terms: [
    { field: ["data", "userId"] }
  ]
})

// 查询
Match(Index("orders_by_user"), "user_001")

三、范围查询 #

3.1 创建范围索引 #

javascript
// 数值范围索引
CreateIndex({
  name: "products_by_price",
  source: Collection("products"),
  values: [
    { field: ["data", "price"] },
    { field: ["ref"] }
  ]
})

// 日期范围索引
CreateIndex({
  name: "orders_by_created_at",
  source: Collection("orders"),
  values: [
    { field: ["data", "createdAt"] },
    { field: ["ref"] }
  ]
})

3.2 Range查询 #

javascript
// 价格范围查询
Paginate(
  Range(
    Match(Index("products_by_price")),
    [10],      // 最小值
    [100]      // 最大值
  )
)

// 日期范围查询
Paginate(
  Range(
    Match(Index("orders_by_created_at")),
    [Time("2024-01-01T00:00:00Z")],
    [Time("2024-12-31T23:59:59Z")]
  )
)

3.3 复合范围查询 #

javascript
// 创建复合范围索引
CreateIndex({
  name: "products_by_category_price",
  source: Collection("products"),
  terms: [
    { field: ["data", "categoryId"] }
  ],
  values: [
    { field: ["data", "price"] },
    { field: ["ref"] }
  ]
})

// 查询特定分类的价格范围
Paginate(
  Range(
    Match(Index("products_by_category_price"), "electronics"),
    [100],
    [1000]
  )
)

四、排序索引 #

4.1 单字段排序 #

javascript
// 创建排序索引
CreateIndex({
  name: "users_by_name_asc",
  source: Collection("users"),
  values: [
    { field: ["data", "name"], order: "asc" },
    { field: ["ref"] }
  ]
})

CreateIndex({
  name: "users_by_name_desc",
  source: Collection("users"),
  values: [
    { field: ["data", "name"], order: "desc" },
    { field: ["ref"] }
  ]
})

// 使用排序索引
Paginate(Match(Index("users_by_name_asc")))
Paginate(Match(Index("users_by_name_desc")))

4.2 多字段排序 #

javascript
// 多字段排序索引
CreateIndex({
  name: "products_sorted",
  source: Collection("products"),
  terms: [
    { field: ["data", "categoryId"] }
  ],
  values: [
    { field: ["data", "price"], order: "asc" },
    { field: ["data", "name"], order: "asc" },
    { field: ["ref"] }
  ]
})

// 查询结果按价格升序,名称升序排列
Paginate(
  Match(Index("products_sorted"), "electronics")
)

4.3 时间排序 #

javascript
// 时间排序索引
CreateIndex({
  name: "orders_by_date_desc",
  source: Collection("orders"),
  terms: [
    { field: ["data", "userId"] }
  ],
  values: [
    { field: ["data", "createdAt"], order: "desc" },
    { field: ["ref"] }
  ]
})

// 获取用户最近的订单
Paginate(
  Match(Index("orders_by_date_desc"), "user_001"),
  { size: 10 }
)

五、唯一索引 #

5.1 创建唯一索引 #

javascript
// 唯一约束索引
CreateIndex({
  name: "users_by_email_unique",
  source: Collection("users"),
  terms: [
    { field: ["data", "email"] }
  ],
  unique: true
})

5.2 使用唯一索引 #

javascript
// 检查唯一性
If(
  Exists(Match(Index("users_by_email_unique"), "tom@example.com")),
  Abort("Email already exists"),
  Create(Collection("users"), {
    data: { email: "tom@example.com", name: "Tom" }
  })
)

// 创建或更新
Let(
  {
    existing: Match(Index("users_by_email_unique"), "tom@example.com")
  },
  If(
    Exists(Var("existing")),
    Update(Select(["ref"], Get(Var("existing"))), {
      data: { name: "Tom Updated" }
    }),
    Create(Collection("users"), {
      data: { email: "tom@example.com", name: "Tom" }
    })
  )
)

六、绑定字段索引 #

6.1 创建绑定索引 #

javascript
// 使用绑定字段
CreateIndex({
  name: "products_by_category_lower",
  source: {
    collection: Collection("products"),
    fields: {
      categoryLower: Query(
        Lambda("doc",
          LowerCase(Select(["data", "category"], Var("doc")))
        )
      )
    }
  },
  terms: [
    { binding: "categoryLower" }
  ]
})

6.2 使用绑定索引 #

javascript
// 查询(不区分大小写)
Match(Index("products_by_category_lower"), "electronics")

6.3 复杂绑定 #

javascript
// 复杂绑定字段
CreateIndex({
  name: "products_search",
  source: {
    collection: Collection("products"),
    fields: {
      searchField: Query(
        Lambda("doc",
          LowerCase(
            Concat([
              Select(["data", "name"], Var("doc"), ""),
              Select(["data", "description"], Var("doc"), ""),
              Select(["data", "category"], Var("doc"), "")
            ], " ")
          )
        )
      )
    }
  },
  terms: [
    { binding: "searchField" }
  ]
})

七、部分索引 #

7.1 创建部分索引 #

javascript
// 只索引活跃产品
CreateIndex({
  name: "active_products",
  source: {
    collection: Collection("products"),
    fields: {
      isActive: Query(
        Lambda("doc",
          And(
            Equals(Select(["data", "status"], Var("doc")), "active"),
            GT(Select(["data", "stock"], Var("doc")), 0)
          )
        )
      )
    }
  },
  terms: [
    { binding: "isActive" }
  ]
})

7.2 使用部分索引 #

javascript
// 查询活跃产品
Paginate(Match(Index("active_products"), true))

八、全文搜索 #

8.1 创建搜索索引 #

javascript
// 创建全文搜索索引
CreateIndex({
  name: "products_fulltext",
  source: {
    collection: Collection("products"),
    fields: {
      searchText: Query(
        Lambda("doc",
          LowerCase(
            Concat([
              Select(["data", "name"], Var("doc"), ""),
              " ",
              Select(["data", "description"], Var("doc"), ""),
              " ",
              Select(["data", "brand"], Var("doc"), "")
            ])
          )
        )
      )
    }
  },
  terms: [
    { binding: "searchText" }
  ]
})

8.2 搜索查询 #

javascript
// 搜索包含关键词的产品
Filter(
  Paginate(Documents(Collection("products"))),
  Lambda("ref",
    Let(
      {
        doc: Get(Var("ref")),
        searchText: LowerCase(
          Concat([
            Select(["data", "name"], Var("doc"), ""),
            " ",
            Select(["data", "description"], Var("doc"), "")
          ])
        )
      },
      ContainsStr(Var("searchText"), LowerCase("iphone"))
    )
  )
)

8.3 多关键词搜索 #

javascript
// 多关键词搜索
Let(
  {
    keywords: ["iphone", "apple"],
    products: Paginate(Documents(Collection("products")))
  },
  Filter(
    Var("products"),
    Lambda("ref",
      Let(
        {
          doc: Get(Var("ref")),
          searchText: LowerCase(
            Concat([
              Select(["data", "name"], Var("doc"), ""),
              " ",
              Select(["data", "description"], Var("doc"), "")
            ])
          )
        },
        And(
          Map(
            Var("keywords"),
            Lambda("keyword",
              ContainsStr(Var("searchText"), LowerCase(Var("keyword")))
            )
          )
        )
      )
    )
  )
)

九、索引优化 #

9.1 索引覆盖查询 #

javascript
// 创建覆盖索引
CreateIndex({
  name: "users_email_name",
  source: Collection("users"),
  terms: [
    { field: ["data", "email"] }
  ],
  values: [
    { field: ["data", "name"] },
    { field: ["data", "status"] },
    { field: ["ref"] }
  ]
})

// 查询时直接获取值,无需Get
Map(
  Paginate(Match(Index("users_email_name"), "tom@example.com")),
  Lambda(["name", "status", "ref"],
    {
      name: Var("name"),
      status: Var("status"),
      ref: Var("ref")
    }
  )
)

9.2 减少索引数量 #

javascript
// 一个复合索引替代多个单字段索引
// 不好的做法:
// - users_by_name
// - users_by_email
// - users_by_status

// 好的做法:
CreateIndex({
  name: "users_search",
  source: Collection("users"),
  terms: [
    { field: ["data", "status"] }
  ],
  values: [
    { field: ["data", "name"] },
    { field: ["data", "email"] },
    { field: ["ref"] }
  ]
})

十、实际应用示例 #

10.1 电商产品搜索 #

javascript
// 产品搜索索引
CreateIndex({
  name: "products_search_index",
  source: Collection("products"),
  terms: [
    { field: ["data", "categoryId"] },
    { field: ["data", "brandId"] }
  ],
  values: [
    { field: ["data", "price"], order: "asc" },
    { field: ["data", "rating"], order: "desc" },
    { field: ["ref"] }
  ]
})

// 搜索查询
Let(
  {
    category: "electronics",
    brand: "apple",
    minPrice: 100,
    maxPrice: 2000
  },
  Filter(
    Paginate(
      Match(Index("products_search_index"), Var("category"), Var("brand"))
    ),
    Lambda(["price", "rating", "ref"],
      And(
        GTE(Var("price"), Var("minPrice")),
        LTE(Var("price"), Var("maxPrice"))
      )
    )
  )
)

10.2 用户活动追踪 #

javascript
// 用户活动索引
CreateIndex({
  name: "user_activities_by_date",
  source: Collection("user_activities"),
  terms: [
    { field: ["data", "userId"] }
  ],
  values: [
    { field: ["data", "timestamp"], order: "desc" },
    { field: ["data", "type"] },
    { field: ["ref"] }
  ]
})

// 获取用户最近活动
Paginate(
  Match(Index("user_activities_by_date"), "user_001"),
  { size: 50 }
)

10.3 订单分析 #

javascript
// 订单分析索引
CreateIndex({
  name: "orders_analytics",
  source: Collection("orders"),
  terms: [
    { field: ["data", "status"] }
  ],
  values: [
    { field: ["data", "createdAt"] },
    { field: ["data", "total"] },
    { field: ["ref"] }
  ]
})

// 按状态统计订单
Map(
  ["pending", "processing", "shipped", "completed"],
  Lambda("status",
    {
      status: Var("status"),
      count: Count(Match(Index("orders_analytics"), Var("status")))
    }
  )
)

十一、总结 #

索引查询要点:

类型 说明
复合索引 多字段查询
范围索引 范围查询
排序索引 结果排序
唯一索引 唯一约束
绑定索引 计算字段
部分索引 条件索引

下一步,让我们学习聚合操作!

最后更新:2026-03-27