LokiJS集合变换(Transforms)功能详解
LokiJS javascript embeddable / in-memory database 项目地址: https://gitcode.com/gh_mirrors/lo/LokiJS
什么是集合变换
集合变换(Collection Transforms)是LokiJS中一个强大的功能,它允许开发者将一系列链式查询操作转换为可存储的对象定义。这种数据定义可以被命名并随集合一起保存在数据库中,类似于传统数据库中的"存储过程"概念。
核心价值与应用场景
集合变换的核心价值在于:
- 查询逻辑封装:将复杂的查询逻辑封装为可重用的模块
- 动态查询构建:通过参数化实现动态查询条件
- 持久化存储:查询逻辑可以随数据库一起保存和加载
典型应用场景包括:
- 开发基于LokiJS数据库的工具
- 创建命名查询(类似存储过程)
- 数据提取前的预处理
- 配合元数据实现自定义解决方案
变换步骤类型详解
变换由有序的步骤对象数组组成,支持以下操作类型:
| 步骤类型 | 描述 | 使用场景 | |---------|------|---------| | find | 基础查询 | 精确匹配文档 | | where | 过滤函数 | 复杂条件过滤 | | simplesort | 简单排序 | 单字段排序 | | compoundsort | 复合排序 | 多字段排序 | | sort | 自定义排序 | 灵活排序需求 | | limit | 结果限制 | 分页查询 | | offset | 结果偏移 | 分页查询 | | update | 文档更新 | 批量修改 | | remove | 文档删除 | 批量删除 | | map | 映射转换 | 数据格式转换 | | mapReduce | 映射归约 | 数据聚合 | | eqJoin | 等值连接 | 集合关联查询 |
基础使用示例
简单变换定义
// 定义一个查找owner为odin的文档的变换
var tx = [
{
type: 'find',
value: {
'owner': 'odin'
}
}
];
保存与执行变换
// 保存变换到集合
userCollection.addTransform('OwnerFilter', tx);
// 执行变换的两种方式
userCollection.chain('OwnerFilter').data();
// 或
userCollection.chain(tx).data();
参数化机制
变换支持强大的参数化功能,使用[%lktxp]
前缀标识参数:
var tx = [
{
type: 'find',
value: {
'owner': '[%lktxp]OwnerName' // 参数化owner字段
}
}
];
// 执行时传入参数
var params = {
OwnerName: 'odin'
};
userCollection.chain(tx, params).data();
复杂变换示例
var tx = [
{
type: 'find',
value: {
owner: {
'$eq': '[%lktxp]customOwner' // 参数化查询条件
}
}
},
{
type: 'where',
value: '[%lktxp]customFilter' // 参数化过滤函数
},
{
type: 'limit',
value: '[%lktxp]customLimit' // 参数化限制数量
}
];
// 定义过滤函数
function myFilter(obj) {
return obj.name.includes("nir");
}
// 执行参数
var params = {
customOwner: 'odin',
customFilter: myFilter,
customLimit: 100
};
// 执行变换
users.chain(tx, params);
动态视图(DynamicView)中的变换
变换可以与动态视图结合使用,实现高效的数据提取:
var dv = coll.addDynamicView('myview');
var tx = [
{
type: 'offset',
value: '[%lktxp]pageStart' // 分页起始位置
},
{
type: 'limit',
value: '[%lktxp]pageSize' // 每页数量
}
];
coll.addTransform('viewPaging', tx);
// 使用变换进行分页查询
var results = dv.branchResultset('viewPaging', {
pageStart: 10,
pageSize: 10
}).data();
自定义元数据扩展
变换支持添加自定义元数据,非常适合需要用户界面管理查询的场景:
var tx = [
{
type: 'meta', // 自定义元数据类型
author: 'admin',
description: '用户分页查询',
params: [
{ name: 'pageStart', type: 'number', desc: '起始位置' },
{ name: 'pageSize', type: 'number', desc: '每页数量' }
]
},
{
type: 'offset',
value: '[%lktxp]pageStart',
desc: '分页起始位置',
lastUpdated: '2023-01-01'
},
// 其他步骤...
];
最佳实践与注意事项
-
性能考量:变换本质上是对链式操作的封装,性能与直接使用链式操作相当
-
参数化限制:where步骤的过滤函数无法直接保存,但可以通过参数化实现
-
终止操作:某些步骤如mapReduce会直接返回结果数组,而不是Resultset对象
-
深度限制:参数替换支持对象层级嵌套,但深度不超过10层
-
未知类型:系统会忽略type未知的步骤,可利用此特性添加自定义信息
总结
LokiJS的集合变换功能提供了一种灵活、可持久化的查询封装机制,它既保持了链式操作的强大功能,又增加了抽象和复用的能力。虽然不强制要求使用,但在需要组织复杂查询或实现动态查询场景时,变换功能将成为开发者的有力工具。
LokiJS javascript embeddable / in-memory database 项目地址: https://gitcode.com/gh_mirrors/lo/LokiJS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考