OrientDB Match查询返回含嵌入顶点的JSON格式问题
我完全理解你的需求——你想要的是嵌套层级清晰的JSON结构,而不是OrientDB MATCH查询默认返回的扁平化结果集。之前用fetch API没搞定很正常,因为默认查询返回的是平铺的行数据,得调整查询方式或者在客户端做些处理,下面给你几个可行的方案:
方案1:用MATCH查询的嵌套投影(推荐,OrientDB 3.0+)
OrientDB 3.0及以上版本支持在MATCH的RETURN子句里直接构建嵌套结构,结合collect()函数来聚合关联数据,刚好能满足你的需求:
MATCH { class: user, as: user, where: (name='tihomir') }.both('hasA'){ as: task, both('hasA'){as: tag} } RETURN { user: { name: user.name, tasks: collect({ name: task.name, tags: collect(tag.name) }) } } AS result
逻辑说明:
- 先用
collect({name: task.name, tags: collect(tag.name)})把同一个用户下的所有任务聚合起来,每个任务里再聚合它关联的标签 - 最后把用户信息和聚合后的任务列表包装成你需要的嵌套结构,返回的
result字段就是符合要求的JSON对象
方案2:用LET子句+SELECT手动组装结构
如果你的OrientDB版本较低,不支持MATCH里的复杂嵌套投影,可以用LET子句分步获取数据,再在SELECT里组装结构:
LET $targetUser = (SELECT FROM user WHERE name='tihomir') LET $userTasks = ( SELECT name, (SELECT name FROM both('hasA') WHERE @class='tag') AS tags FROM both('hasA') WHERE @class='task' FROM $targetUser ) SELECT { user: { name: $targetUser.name, tasks: $userTasks } } AS result
逻辑说明:
- 先通过
$targetUser获取目标用户 - 再通过
$userTasks获取该用户关联的所有任务,同时嵌套查询每个任务的标签列表 - 最后把用户信息和任务列表组装成嵌套结构返回
方案3:客户端侧数据重组(兼容所有版本)
如果服务器端的查询调整有困难,也可以先获取扁平化的查询结果,再在客户端用代码把数据重组为嵌套结构。比如用JavaScript处理fetch返回的结果:
// 假设fetch返回的原始扁平化数据是这样的数组 const flatQueryResults = [ { user: { name: 'tihomir' }, task_name: 'task1', tag_name: 'tag1' }, { user: { name: 'tihomir' }, task_name: 'task1', tag_name: 'tag2' }, { user: { name: 'tihomir' }, task_name: 'task2', tag_name: 'tag3' } ]; // 重组为嵌套结构 const nestedResult = flatQueryResults.reduce((acc, item) => { // 查找或创建当前用户 let currentUser = acc.find(u => u.user.name === item.user.name); if (!currentUser) { currentUser = { user: { name: item.user.name }, tasks: [] }; acc.push(currentUser); } // 查找或创建当前任务 let currentTask = currentUser.tasks.find(t => t.name === item.task_name); if (!currentTask) { currentTask = { name: item.task_name, tags: [] }; currentUser.tasks.push(currentTask); } // 避免重复添加标签 if (!currentTask.tags.find(t => t.name === item.tag_name)) { currentTask.tags.push({ name: item.tag_name }); } return acc; }, []);
逻辑说明:
- 用
reduce遍历扁平化的结果,逐步构建用户、任务、标签的层级关系 - 每次遍历检查当前用户/任务是否已存在,不存在则创建,避免重复数据
内容的提问来源于stack exchange,提问作者thinklinux
相关产品推荐
相关产品推荐

