ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OneUptime API 查询过滤器 Includes 详解:用 JSON 实现多值集合匹配

OneUptime API 查询过滤器 Includes 详解:用 JSON 实现多值集合匹配 OneUptime API 查询过滤器 Includes 详解用 JSON 实现多值集合匹配【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime本文围绕 OneUptime 官方 API 参考文档中的 Includes 查询代码示例系统讲解Includes查询过滤器的 JSON 请求格式、字段语义、在数据库层的 SQL 转换原理以及它在标签Labels、监控类型、库存状态等场景下的实战用法。读完本文你将能够独立构造Includes查询体理解其与EqualTo、IncludesAll、IncludesNone等兄弟过滤器的差异并能在 OneUptime 的查询 API 中正确使用多值匹配过滤。Includes 查询过滤器是什么在 OneUptime 的 API 查询体系中Includes是一种多值包含查询过滤器它匹配字段值属于给定数组中任意一个值的所有对象。用集合的语言描述就是判断field ∈ value[]等价于 SQL 中的IN (...)语义。官方数据类型注册表在 App/FeatureSet/APIReference/Utils/DataTypes.ts 中将其定义为A query filter that matches objects where a field value is included in the specified array of values.典型的应用场景包括按标签集合过滤资源找出带有某个标签或某几个标签之一的所有监控器、事件、告警按枚举集合过滤找出monitorType为Ping、API或Port之一的所有监控器按状态集合过滤找出库存资源中inventoryStatus为stale或recent的记录按 ID 集合过滤一次请求内批量按主键或外键筛选多个目标对象。请求体格式从官方代码示例说起官方示例文件 Includes.md 给出了一个完整的查询请求体{ query: { labels: { _type: Includes, value: [ aaa00000-aaaa-aaaa-aaaa-aaaaaaaaaaaa, bbb00000-bbbb-bbbb-bbbb-bbbbbbbbbbbb ] } } }该请求体语义为查询所有labels标签字段值为aaa00000-aaaa-aaaa-aaaa-aaaaaaaaaaaa或bbb00000-bbbb-bbbb-bbbb-bbbbbbbbbbbb中任意一个的对象注意示例文件中\_type的下划线转义在真实 JSON 中即为_type。请求体结构拆解层级字段类型说明顶层queryobject查询过滤条件容器其 key 为要过滤的字段名value 为过滤器对象过滤器_typestring过滤器类型标记此处固定为Includes过滤器valuearray候选值数组元素类型支持string、number以及后端支持的ObjectID这个 _type判别字段 value载荷 的序列化协议是整个 OneUptime 查询层的通用线格式。官方数据类型详情页 App/FeatureSet/APIReference/Service/DataTypeDetail.ts 对Includes的属性描述为value必填Arraystring | number一个候选值数组只要字段值等于其中任意一个即匹配。请求体的加载与渲染在 API Reference 站点实现中Service/DataType.ts 通过LocalCache.getOrSetString缓存并读取Includes.md内容将其渲染到数据类型指南页面供开发者在浏览参考文档时直接复制使用pageData[includesCode] await LocalCache.getOrSetString( data-type, includes, async () { return await LocalFile.read( ${CodeExamplesPath}/DataTypes/Includes.md, ); }, );这意味着该示例是文档站点上Includes数据类型的官方配套样例可以直接作为手写查询体的起点。后端实现Includes 查询操作符的序列化与反序列化Includes在类型系统中被建模为一个查询操作符Query Operator其核心实现在 Common/Types/BaseDatabase/Includes.tsexport type IncludesType Arraystring | ArrayObjectID | Arraynumber; export default class Includes extends QueryOperatorIncludesType { private _values: IncludesType []; public get values(): IncludesType { return this._values; } public set values(v: IncludesType) { this._values v; } public constructor(values: IncludesType) { super(); this.values values; } public override toJSON(): JSONObject { return { _type: ObjectType.Includes, value: (this as Includes)._values, }; } public static override fromJSON(json: JSONObject): Includes { if (json[_type] ObjectType.Includes) { const valuesArray: Arraystring []; for (const value of (json[value] as Arraystring) || []) { valuesArray.push(JSONFunctions.deserializeValue(value) as string); } return new Includes(valuesArray); } throw new BadDataException(Invalid JSON: JSON.stringify(json)); } }关键点受支持的元素类型IncludesType明确限定为string、ObjectIDUUID 标识符或number与文档示例中的两个 UUID 字符串一致线格式对称toJSON()输出{ _type: Includes, value: [...] }fromJSON()严格校验_type后重建对象保证请求从浏览器经 HTTP 到达服务端后能够无损还原ObjectType.Includes枚举该判别值定义于 Common/Types/JSON.ts与IncludesAll、IncludesNone、InBetween等过滤器一同被注册在 JSON 序列化类型表中。底层原理Includes 如何转换为 SQL普通标量列的转换SQLIN当Includes作用于普通标量列时Common/Server/Types/Database/QueryUtil.ts 会根据列元数据类型做分派} else if ( query[key] query[key] instanceof Includes tableColumnMetadata ) { if ( tableColumnMetadata.type TableColumnType.EntityArray || tableColumnMetadata.type TableColumnType.Entity ) { query[key] (query[key] as Includes).values as any; } else { query[key] QueryHelper.any((query[key] as Includes).values) as any; } }当目标列为Entity / EntityArray 关系列如labels这种多对多标签关联直接传入值数组交由 TypeORM 处理关系查询当目标列为普通标量列如monitorType枚举字符串则交给QueryHelper.any()。QueryHelper.any()与底层私有方法in()实现在 Common/Server/Types/Database/QueryHelper.tspublic static any( values: Arraystring | ObjectID | number, ): FindWherePropertyany { return this.in(values); // any and in are the same } private static in( values: Arraystring | ObjectID | number, ): FindWherePropertyany { values values.map((value) value.toString()); const rid: string Text.generateRandomText(10); if (!values || values.length 0) { return Raw(() { return TRUE FALSE; // this will always return false }, {}); } return Raw( (alias: string) { return (${alias} IN (:...${rid})); }, { [rid]: values }, ); }由此可知标量列上的Includes最终编译为参数化 SQLWHERE 字段 IN (:...参数)所有元素统一toString()后绑定为参数天然防 SQL 注入参数绑定而非字符串拼接空数组的特殊语义若传入value: []生成的谓词恒为TRUE FALSE即匹配不到任何对象——空数组按匹配零行处理fail closed而非匹配全部。JSONB 列上的 Includes展开为 OR 等值判断当Includes作用于customFields这类 JSONB 列时走的是 Common/Server/Types/Database/JSONColumnQuery.ts 中的专用分支if (value instanceof Includes) { const values: ArrayScalarValue toScalarArray(value.values); return values.length 0 ? null : this.anyOf(values); }anyOf将候选数组展开为若干个该键的标量值等于 X 或数组包含 X的谓词以OR连接。其底层equals谓词同时处理两种存储形态键值以标量存储单选用例col - key CAST(:v AS TEXT)键值以数组存储多选用例col - key CAST(:v AS JSONB)jsonb 包含运算。这正是 JSONColumnQuery.ts 中注释强调的value matches whether it is stored as a scalar or inside an array无论自定义字段被配置为单选还是多选同一个Includes查询都能得到一致结果。同时每个值都会被展开成独立谓词因此该模块设置了MAX_JSON_QUERY_VALUES_PER_KEY 200的上限防止无限值列表把一条查询编译成巨型 SQL。阈值与边界JSONB 列过滤器单键最多200 个候选值整条 JSON 查询最多50 个键单个键名最长500 字符超限即抛出BadDataException返回 400普通 SQL 列上的Includes无此显式上限但同样遵循数据库参数数量限制建议按业务面大小控制候选值规模。使用示例真实测试用例验证仓库测试代码可以直接印证上述行为。例如 Common/Tests/Server/API/DashboardPublicResourceListAPI.test.ts 中通过new Includes(...)构造标签与监控类型过滤monitorType: new Includes([Ping]), labels: new Includes([fixedLabelId]), labels: new Includes([firstLabelId, secondLabelId]),而 Common/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.ts 展示了库存过滤场景expect(query[entityType]).toEqual(new Includes([EntityType.Service])); expect(query[inventoryStatus]).toEqual(new Includes([stale])); new Includes([EntityType.Host, EntityType.KubernetesPod]),可以看到Includes在项目内被广泛用于资源列表 API 的标签多选过滤labels字段EntityArray 列监控器类型过滤monitorType枚举库存资源的实体类型、数据源、存活状态过滤遥测指标按host.name等属性多值过滤如 DashboardPublicMetricsAggregateAPI.test.ts 中的attributes: { host.name: new Includes([web-1, web-2]) }。与其他查询过滤器的对比与选型Includes并非唯一的集合型过滤器。理解它与其他操作符的差异有助于写出正确的查询过滤器语义典型 JSON说明Includes字段值 ∈ 候选集合OR{ _type: Includes, value: [a, b] }本文主角匹配任一值IncludesAll数组字段同时包含集合中所有值AND{ _type: IncludesAll, value: [a, b] }要求数组字段同时含 a 与 b见 Common/Types/BaseDatabase/IncludesAll.tsIncludesNone数组字段不含集合中任意值NOT IN{ _type: IncludesNone, value: [a] }排除型过滤见 Common/Types/BaseDatabase/IncludesNone.tsEqualTo字段值等于单值{ _type: EqualTo, value: a }单值等值比较见 EqualTo.mdEqualToOrNull字段值等于单值或为 null{ _type: EqualToOrNull, value: a }等值 空值兜底InBetween字段值落在闭区间 [start, end]{ _type: InBetween, ... }数值/日期区间过滤实现层面IncludesAll与IncludesNone的完整行为同样定义在 JSONColumnQuery.ts 的build()分支中allOf用 AND 连接、IncludesNone对整个 OR 谓词取反而 JSON 序列化判别枚举集中在 Common/Types/JSON.ts。当需要任选其一时用Includes需要全部满足时用IncludesAll需要排除若干值时用IncludesNone。使用建议与注意事项标签过滤的首选方案多对多标签labels过滤请直接使用Includes请求体会被正确路由到 EntityArray 关系查询路径空数组行为value: []表示匹配不到任何对象若想表达不限制应省略该过滤器字段而不是传空数组候选值类型一致性value元素应使用与字段类型匹配的字符串如 UUID、数字或枚举文本ObjectID在序列化后即为 UUID 字符串可安全混用JSONB 自定义字段作用于customFields时值既可以匹配标量存储单选也可以匹配数组存储多选无需关心字段在界面上的配置形态规模控制JSONB 列单键最多 200 个候选值普通列虽无硬性上限仍建议控制规模以保证 SQL 执行性能。小结Includes是 OneUptime 查询体系中实现多值集合匹配的核心过滤器。从 官方代码示例 出发我们梳理了其{ _type, value }的线格式协议、Includes.ts 中的类型实现、QueryUtil.ts 与 QueryHelper.ts 中的 SQLIN转换以及 JSONColumnQuery.ts 中针对 jsonb 列的 OR 展开语义并通过仓库测试用例验证了其在标签、监控类型、库存状态等场景的真实用法。掌握Includes及其兄弟过滤器即可高效构造 OneUptime API 的复杂列表查询。【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表