SpaceX-API Landing Pad 数据模型详解:v4 Schema 字段全解析与查询实战
【免费下载链接】SpaceX-API:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.项目地址: https://gitcode.com/gh_mirrors/spa/SpaceX-API
Landing Pad(着陆场)是 SpaceX 火箭一级助推器陆地回收与返回式着陆的关键基础设施,本文以 SpaceX-API 仓库 docs/landpads/v4/schema.md 为核心,逐字段剖析/v4/landpads端点的官方数据结构,并结合仓库源码 models/landpads.js 与 routes/landpads/v4/index.js 验证字段约束、枚举值与数据关联,最后给出基于真实响应示例的查询、过滤与分页实战方案。读完本文,你将能准确构造 Landing Pad 读写请求、理解landing_attempts等字段的统计口径,并复用该 Schema 组织自有太空数据服务。
一、Landing Pad 在 SpaceX-API 中的定位
在 SpaceX-API 的 v4 版本中,Landing Pad 数据通过统一的版本化路由对外暴露,路由前缀支持v4与latest双版本别名(见 routes/landpads/v4/index.js 中的prefix: '/(v4|latest)/landpads')。所有GET与POST /query请求均经过 Redis 缓存,根据 docs/README.md 中的缓存策略说明,landpads 的标准缓存时长为 5 分钟(与 capsules、cores、launchpads、crew、ships、payloads 同级),而源码 routes/landpads/v4/index.js 中通过cache(300)中间件传入的 300 秒也正是该缓存时长。这意味着在连续查询同一批着陆场数据时,命中缓存的响应速度会显著提升,但也意味着新增数据最多需要 5 分钟才能对读请求可见。
Landing Pad 数据对象与 Launch(发射)、Core(芯级)之间存在引用关系:每个着陆场通过launches数组关联其承载过的发射任务;反过来,Launch 文档的cores[].landpad字段也指向该着陆场。这种双向关联是理解本 Schema 中launches字段类型设计的关键。
二、官方 Schema 完整呈现
以下 JSON 即 docs/landpads/v4/schema.md 中定义的官方字段约束:
{ "name": { "type": "String", "default": null }, "full_name": { "type": "String", "default": null }, "status": { "type": "String", "enum": [ "active", "inactive", "unknown", "retired", "lost", "under construction" ], "required": true }, "type": { "type": "String", "default": null }, "locality": { "type": "String", "default": null }, "region": { "type": "String", "default": null }, "latitude": { "type": "Number", "default": null }, "longitude": { "type": "Number", "default": null }, "landing_attempts": { "type": "Number", "default": 0 }, "landing_successes": { "type": "Number", "default": 0 }, "wikipedia": { "type": "String", "default": null }, "details": { "type": "String", "default": null }, "launches": [ { "type": "UUID" } ] }三、字段级深度解析
将上述 Schema 与 models/landpads.js 中的 Mongoose 实现逐一对齐,可以得到每个字段的完整语义:
3.1 标识与命名字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | String | null | 简短代号,如LZ-1、LZ-2、SLS等,用于快速识别 |
full_name | String | null | 完整名称,如Landing Zone 1(着陆区 1) |
type | String | null | 着陆方式/场地类型。实际数据中常见值为RTLS(Return To Launch Site,返回发射场陆地回收),此外还存在其他回收形态(如 ASDS 海上驳船由 ships 数据集管理,见 docs/ships/v4/all.md) |
其中name、full_name、details三个字段在源码 models/landpads.js 中被联合建成了text 文本索引:
const index = { name: 'text', full_name: 'text', details: 'text', }; landpadSchema.index(index);这意味着可以通过 MongoDB 的$text操作符对这三类字段做全文搜索,例如搜索包含 "Florida" 或 "Cape Canaveral" 字样的着陆场详情。
3.2 状态枚举status
status是本 Schema 中唯一一个required: true(必填)且带枚举约束的字段,取值空间由 models/landpads.js 严格限定为六种:
active— 当前可用/在役inactive— 当前停用但保留unknown— 状态未知retired— 已退役lost— 已丢失/不可用under construction— 建设中(含扩建,如 LZ-2 从无到有)
枚举约束保证了数据可枚举、可过滤、可建立一致的统计口径。任何不符合该枚举的写入请求,都会被 routes/landpads/v4/index.js 中update路由使用的{ runValidators: true }选项拦截并返回400。
3.3 地理位置字段
| 字段 | 类型 | 说明 |
|---|---|---|
locality | String | 城市/区域级地名,如Cape Canaveral |
region | String | 州/省级行政区,如Florida |
latitude | Number | 纬度(十进制度数,北纬为正) |
longitude | Number | 经度(十进制度数,西经为负) |
经纬度字段可配合地图可视化工具直接用于落点绘制,例如 LZ-2 的坐标28.485833, -80.544444位于佛罗里达卡纳维拉尔角附近。
3.4 回收统计字段
| 字段 | 类型 | 默认值 | 语义 |
|---|---|---|---|
landing_attempts | Number | 0 | 该着陆场累计的着陆尝试次数 |
landing_successes | Number | 0 | 该着陆场累计的成功着陆次数 |
这两个字段不是由用户手工维护的,而是由定时作业自动统计生成。在 jobs/landpads.js 中,作业对每个 landpad 分别发起两次launches/query查询:
- 尝试次数:统计
upcoming: false, success: true且cores中landpad等于当前着陆场 ID、landing_attempt: true的已发射任务; - 成功次数:在上述条件基础上追加
landing_success: true。
随后通过PATCH /landpads/:id将landing_attempts与landing_successes写回。该作业在 jobs/worker.js 中以*/10 * * * *的 Cron 表达式每 10 分钟执行一次。因此调用方可以放心地把这两个字段当作权威统计值使用,而无需自行对 Launch 数据做聚合。
3.5 描述与资料字段
| 字段 | 类型 | 说明 |
|---|---|---|
wikipedia | String | 维基百科词条 URL,用于进一步查阅场地历史 |
details | String | 场地详细描述,通常包含历史沿革,例如 LZ-1 曾于 2015 年 12 月完成 Falcon 9 首次历史性陆地回收,其原址 LC-13 曾用于发射早期 Atlas 导弹/火箭,后扩建出 LZ-2 用于 Falcon Heavy 侧助推器 RTLS 任务 |
3.6 关联发射字段launches
"launches": [ { "type": "UUID" } ]在 API 文档层,launches是存放 Launch 文档 ID(UUID 形态的 24 位十六进制字符串)的数组。在存储层,models/landpads.js 将其实现为:
launches: [{ type: mongoose.ObjectId, ref: 'Launch', }]即一个mongoose.ObjectId数组,外键指向Launch集合。这意味着:
- 你可以把
launches里的每个 ID 用于GET /v4/launches/:id单独取回发射详情; - 也可以借助查询接口的
populate选项一次性把这些 ID 展开为完整的 Launch 文档(详见本文第四节)。
3.7 Schema 文档未列出、但源码中存在的字段
从源码结构看,models/landpads.js 还定义了images字段(images.large为字符串数组),用于存放着陆场的大图 URL;docs/landpads/v4/schema.md 未将其列入,属于官方文档对字段集的轻微精简。在实际GET响应中该字段是否返回,以线上 API 返回体为准——本文第五节给出的示例响应中未包含该字段。
四、关联字段的填充(populate)实战
由于launches数组存放的是 Launch 文档 ID,想要一次拿全着陆场与对应发射的完整信息,可以利用 docs/queries.md 中描述的populate机制。向POST /v4/landpads/query发送:
{ "query": {}, "options": { "populate": [ "launches" ] } }即可把launches数组中的每个 UUID 替换为对应的完整 Launch 文档。更精细的做法是只提取感兴趣的字段:
{ "query": {}, "options": { "populate": [ { "path": "launches", "select": { "name": 1, "flight_number": 1, "date_utc": 1 } } ] } }此时每个发射对象将只返回name、flight_number、date_utc与id,显著压缩响应体积。populate还支持嵌套填充(例如在发射文档内部继续展开rocket),可满足多层联查场景。
五、基于 Schema 的 API 调用方式
围绕 docs/landpads/v4/schema.md 定义的字段结构,/v4/landpads提供了三类读接口(均无需鉴权,完整路由实现见 routes/landpads/v4/index.js):
5.1 获取全部着陆场GET /v4/landpads
返回所有 Landing Pad 文档组成的数组,每个元素遵循本 Schema。参考 docs/landpads/v4/all.md 中的真实响应示例:
[ { "name": "LZ-2", "full_name": "Landing Zone 2", "status": "active", "type": "RTLS", "locality": "Cape Canaveral", "region": "Florida", "latitude": 28.485833, "longitude": -80.544444, "landing_attempts": 3, "landing_successes": 3, "wikipedia": "https://en.wikipedia.org/wiki/Landing_Zones_1_and_2", "details": "SpaceX's first east coast landing pad is Landing Zone 1, ...", "launches": [ "5eb87d13ffd86e000604b360", "5eb87d2dffd86e000604b376", "5eb87d35ffd86e000604b37a" ], "id": "5e9e3032383ecb90a834e7c8" } ]注意该示例中字段为id而非_id,这是 models/landpads.js 中mongoose-id插件的效果——它在序列化时把 MongoDB 的_id映射为对外友好的id字段。
5.2 获取单个着陆场GET /v4/landpads/:id
URL 参数id为 Landing Pad 的 24 位十六进制 ID(如5e9e3032383ecb90a834e7c8)。响应体结构与上文示例完全一致;若 ID 不存在,返回404 NOT FOUND,响应体为Not Found(见 docs/landpads/v4/one.md)。对应路由实现在 routes/landpads/v4/index.js:
router.get('/:id', cache(300), async (ctx) => { const result = await Landpad.findById(ctx.params.id); if (!result) { ctx.throw(404); } ctx.status = 200; ctx.body = result; });5.3 自定义查询POST /v4/landpads/query
请求体为{ "query": {}, "options": {} },其中query接受任何合法的 MongoDBfind()查询,options支持select、sort、offset、page、limit、pagination、populate等分页与输出控制参数(详见 docs/queries.md)。路由在 routes/landpads/v4/index.js 中通过Landpad.paginate(query, options)执行,mongoose-paginate-v2插件为 models/landpads.js 所挂载。
响应为分页包装结构,参考 docs/landpads/v4/query.md 的示例(totalDocs: 7表明当前数据集共有 7 个着陆场记录):
{ "docs": [ { "name": "LZ-1", "full_name": "Landing Zone 1", "status": "active", "type": "RTLS", "locality": "Cape Canaveral", "region": "Florida", "latitude": 28.485833, "longitude": -80.544444, "landing_attempts": 15, "landing_successes": 14, "wikipedia": "https://en.wikipedia.org/wiki/Landing_Zones_1_and_2", "details": "...", "launches": [ "5eb87cefffd86e000604b342", "5eb87cf9ffd86e000604b349", "5eb87cfefffd86e000604b34d" ], "id": "5e9e3032383ecb267a34e7c7" } ], "totalDocs": 7, "offset": 0, "limit": 10, "totalPages": 1, "page": 1, "pagingCounter": 1, "hasPrevPage": false, "hasNextPage": false, "prevPage": null, "nextPage": null }查询请求若包含非法字段或非法查询语法,接口返回400 Bad Request,响应体为 Mongoose 报错信息并附带修正建议。
六、常用查询场景示例
结合本 Schema 的字段设计,以下查询在实战中最常用:
1. 只看当前在役的陆地回收场:
{ "query": { "status": "active", "type": "RTLS" }, "options": { "sort": { "name": "asc" } } }2. 按区域过滤并按回收成功率排序(可先用 populate 展开发射以做关联分析):
{ "query": { "region": "Florida" }, "options": { "sort": { "landing_successes": "desc" }, "limit": 5 } }3. 全文搜索场地描述(利用 text 索引):
{ "query": { "$text": { "$search": "Cape Canaveral" } } }4. 只返回坐标与统计字段,用于地图绘制,压缩带宽:
{ "query": {}, "options": { "select": { "name": 1, "latitude": 1, "longitude": 1, "landing_attempts": 1, "landing_successes": 1 } } }5. 关闭分页,一次取回全部记录(适用于totalDocs数量小的集合):
{ "query": {}, "options": { "pagination": false } }其中第 5 种方式正是 jobs/landpads.js 内部抓取全量着陆场数据的做法,可作为大数据集之外小规模同步场景的参考范本。
七、写入与维护:Schema 约束如何生效
虽然对外公开的读接口无需鉴权,但所有写操作(创建、更新、删除)都必须通过spacex-key请求头携带 API Key 完成鉴权,并经过 middleware/authz.js 的角色权限校验(landpad:create/landpad:update/landpad:delete)。相关路由完整实现了 CRUD(见 routes/landpads/v4/index.js):
POST /v4/landpads— 按请求体创建新文档,成功后返回201;PATCH /v4/landpads/:id— 部分更新指定文档,runValidators: true会触发status枚举等 Schema 校验,非法值返回400;DELETE /v4/landpads/:id— 删除指定文档。
写请求若违反 Schema 约束(如status传入枚举之外的字符串、缺少必填的status、latitude传入非数值),Mongoose 校验器会拒绝写入并抛出错误,由路由捕获后以400 Bad Request返回错误消息。这一机制保证了线上数据的字段类型与枚举一致性。
八、总结
Landing Pad 的 v4 Schema 是一份精简而完整的领域数据模型:status的六值枚举提供了状态机式的可枚举语义,latitude/longitude支撑地理可视化,landing_attempts/landing_successes由 jobs/landpads.js 每 10 分钟自动重算,launches数组则通过外键与 populate 机制打通了与 Launch 数据的关联分析。无论是消费GET /v4/landpads、GET /v4/landpads/:id做展示,还是利用POST /v4/landpads/query做过滤、排序、全文检索与分页,本文所整理的字段语义与查询示例均可直接复制使用。深入阅读 models/landpads.js 与 routes/landpads/v4/index.js 源码,还能进一步掌握文本索引、外键引用、分页插件与权限控制等实现细节,为自建同类数据服务提供参考。
【免费下载链接】SpaceX-API:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.项目地址: https://gitcode.com/gh_mirrors/spa/SpaceX-API
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考