You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SurrealDB图查询结果反序列化问题求助

SurrealDB图关系查询结果反序列化解决方案

你的问题出在查询返回的结构不是直接的数组,而是一个包含目标数组的对象。SELECT ->owns->track FROM user:0的返回结果是一个以->owns->track为键、Thing数组为值的对象,而非顶层直接是数组,所以直接反序列化成Vec<Thing>或其他单一类型会失败。

下面提供三种可行的解决方法:

方法1:自定义结构体匹配返回结构

通过serde的字段别名特性,定义一个结构体来匹配查询返回的对象结构:

use serde::Deserialize;
use surrealdb::sql::Thing;

#[tokio::main]
async fn main() -> surrealdb::Result<()> {
    let db = surrealdb::engine::any::connect("mem://").await?;
    db.use_ns("test").use_db("test").await?;
    
    // 初始化数据
    db.query("CREATE user:0").await?;
    db.query("CREATE user:1").await?;
    db.query("CREATE track:0").await?;
    db.query("CREATE track:1").await?;
    db.query("CREATE track:2").await?;
    db.query("CREATE track:3").await?;
    db.query("CREATE track:10").await?;
    db.query("RELATE user:0->owns->track:0").await?;
    db.query("RELATE user:0->owns->track:1").await?;
    db.query("RELATE user:0->owns->track:2").await?;
    db.query("RELATE user:0->owns->track:3").await?;
    db.query("RELATE user:1->owns->track:0").await?;
    db.query("RELATE user:1->owns->track:10").await?;

    // 定义匹配返回结构的结构体
    #[derive(Deserialize, Debug)]
    struct UserTracks {
        #[serde(rename = "->owns->track")]
        tracks: Vec<Thing>,
    }

    let res = db.query("SELECT ->owns->track FROM user:0").await?;
    let user_tracks: UserTracks = res.take(0)?;
    dbg!(&user_tracks.tracks);

    Ok(())
}

方法2:用HashMap接收

直接用HashMap<String, Vec<Thing>>接收返回对象,再通过键提取目标数组:

// 初始化数据部分省略
let res = db.query("SELECT ->owns->track FROM user:0").await?;
let track_map: std::collections::HashMap<String, Vec<Thing>> = res.take(0)?;
let tracks = track_map.get("->owns->track").unwrap();
dbg!(tracks);

方法3:通过Value手动解析

先将结果反序列化为surrealdb::sql::Value,再手动提取数组并转换为Vec<Thing>:

// 初始化数据部分省略
let res = db.query("SELECT ->owns->track FROM user:0").await?;
let value: surrealdb::sql::Value = res.take(0)?;
if let surrealdb::sql::Value::Object(obj) = value {
    if let Some(surrealdb::sql::Value::Array(arr)) = obj.get("->owns->track") {
        let things: Vec<Thing> = arr.iter()
            .filter_map(|v| v.as_thing())
            .cloned()
            .collect();
        dbg!(&things);
    }
}

错误原因说明

  • 用Vec<Thing>报错是因为查询返回的顶层是对象(map),而非数组(sequence),反序列化器预期序列但收到map。
  • 用Thing报错是因为顶层不是单个Thing实例,而是包含多个Thing的数组的对象。

内容的提问来源于stack exchange,提问作者sabjorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:52:53