Rust数据查询引擎Trustfall核心库trustfall_core的使用,支持高效灵活的数据查询与处理
Rust数据查询引擎Trustfall核心库trustfall_core的使用,支持高效灵活的数据查询与处理
Trustfall是一个可以查询各类数据源的查询引擎,从API和数据库到磁盘上的各种文件,甚至AI模型都可以查询。
浏览器中尝试Trustfall
Trustfall Playground支持对以下公共数据源运行查询:
- HackerNews REST APIs
- 顶级Rust库的rustdoc JSON
例如,可以运行查询:“哪些GitHub或Twitter用户正在评论关于OpenAI的故事?”
10分钟技术演讲+演示
Trustfall曾在HYTRADBOI 2022会议上进行了"如何查询(几乎)一切"的技术演讲。
演示从演讲中展示跨API查询的执行:“哪些GitHub Actions被用在HackerNews首页上得分≥10的项目中?”
演示执行了以下跨HackerNews和GitHub API以及YAML格式的GitHub仓库工作流文件的查询:
{
HackerNewsTop(max: 200) {
... on HackerNewsStory {
hn_score: score @filter(op: ">=", value: ["$min_score"]) @output
link {
... on GitHubRepository {
repo_url: url @output
workflows {
workflow: name @output
workflow_path: path @output
jobs {
job: name @output
step {
... on GitHubActionsImportedStep {
step: name @output
action: uses @output
}
}
}
}
}
}
}
}
}
查询真实世界数据的示例
- HackerNews APIs,包括查询语言概述和查询REST API的示例
- RSS/Atom feeds,展示如何查询结构化数据如RSS/Atom feeds
- 机场天气数据(METAR),展示如何查询航空天气报告的CSV数据
Trustfall还支持cargo-semver-checks
语义版本检查工具。
在新数据源上使用Trustfall
最简单的方法是实现BasicAdapter
trait。
Python绑定可用,并在引擎每次更改时自动构建;最新的版本可以下载。Python入门指南即将发布。
目录注册表
trustfall
是外观crate。这是使用Trustfall的首选方式。trustfall_core
包含查询引擎内部trustfall_derive
定义简化数据源插入的宏pytrustfall
包含Trustfall的Python绑定trustfall_wasm
是Trustfall的WASM构建trustfall_filetests_macros
是一个用于生成由文件定义的测试案例的过程宏experiments
包含各种实验性项目
完整示例代码
以下是一个使用trustfall_core的完整示例:
use trustfall_core::{ir::FieldValue, interpreter::BasicAdapter, schema::Schema};
// 1. 定义你的数据源适配器
struct MyAdapter;
impl BasicAdapter for MyAdapter {
type Vertex = String;
fn resolve_starting_vertices(
&self,
edge_name: &str,
_parameters: &[(&str, FieldValue)],
) -> Vec<Self::Vertex> {
match edge_name {
"Root" => vec!["root_node".to_string()],
_ => vec![],
}
}
fn resolve_property(
&self,
context: &Self::Vertex,
type_name: &str,
property_name: &str,
) -> FieldValue {
match (context.as_str(), type_name, property_name) {
("root_node", "Root", "name") => FieldValue::String("Root Node".to_string()),
_ => FieldValue::Null,
}
}
fn resolve_neighbors(
&self,
context: &Self::Vertex,
type_name: &str,
edge_name: &str,
) -> Vec<Self::Vertex> {
match (context.as_str(), type_name, edge_name) {
("root_node", "Root", "children") => vec!["child1".to_string(), "child2".to_string()],
_ => vec![],
}
}
}
// 2. 定义你的GraphQL schema
const SCHEMA: &str = r#"
type Root {
name: String
children: [Child]
}
type Child {
name: String
}
schema {
query: Root
}
"#;
fn main() {
// 3. 创建schema
let schema = Schema::parse(SCHEMA).expect("valid schema");
// 4. 创建适配器实例
let adapter = MyAdapter;
// 5. 准备查询
let query = r#"
{
Root {
name @output
children {
name @output
}
}
}
"#;
// 6. 执行查询
let results = trustfall_core::execute_query(&schema, &adapter, query)
.expect("valid query execution");
// 7. 处理结果
for result in results {
println!("Result: {:?}", result);
}
}
这个示例展示了如何:
- 创建一个基本适配器实现
BasicAdapter
trait - 定义GraphQL schema
- 解析schema
- 创建适配器实例
- 准备查询
- 执行查询
- 处理结果
Trustfall提供了灵活的方式来查询各种数据源,同时保持高效的性能。通过实现适配器接口,你可以轻松地将Trustfall集成到现有的数据系统中。
1 回复
以下是基于您提供的Trustfall核心库使用指南内容的完整示例demo:
// 1. 添加依赖到Cargo.toml
/*
[dependencies]
trustfall_core = "0.12.0"
*/
use trustfall_core::{
schema::Schema,
Adapter,
AdapterContext,
EdgeParameters,
execute_query,
QueryContext,
VertexIterator
};
// 2. 定义数据模型和顶点类型
#[derive(Debug)]
struct Person {
name: String,
age: Option<i64>,
friends: Vec<Person>,
}
// 3. 实现适配器
struct PersonAdapter;
impl Adapter for PersonAdapter {
type Vertex = Person;
fn resolve_starting_vertices(
&self,
edge_name: &str,
_parameters: &EdgeParameters,
_ctx: &AdapterContext,
) -> VertexIterator<Self::Vertex> {
// 模拟数据源
let people = vec![
Person {
name: "Alice".to_string(),
age: Some(25),
friends: vec![
Person {
name: "Bob".to_string(),
age: Some(30),
friends: vec![],
},
Person {
name: "Charlie".to_string(),
age: Some(22),
friends: vec![],
},
],
},
Person {
name: "John".to_string(),
age: Some(35),
friends: vec![
Person {
name: "Jane".to_string(),
age: Some(28),
friends: vec![],
},
],
},
];
// 只返回Person类型的顶点
if edge_name == "Person" {
Box::new(people.into_iter())
} else {
Box::new(std::iter::empty())
}
}
}
fn main() {
// 定义Schema
let schema = Schema::parse(
r#"
type Person {
name: String!
age: Int
friends: [Person!]!
}
"#,
).expect("Valid schema");
// 执行基础查询
let query = r#"
{
Person {
name @output
age @output
friends {
name @output
}
}
}
"#;
let results = execute_query::<PersonAdapter>(
&schema,
PersonAdapter,
query,
std::collections::HashMap::new(),
QueryContext::default(),
).expect("Query failed");
println!("基础查询结果: {:?}", results);
// 执行参数化查询
let param_query = r#"
query FindPerson($name: String!) {
Person {
name @filter(op: "=", value: ["$name"])
age @output
friends {
name @output
}
}
}
"#;
let variables = std::collections::HashMap::from([
("name".to_string(), "Alice".into())
]);
let param_results = execute_query::<PersonAdapter>(
&schema,
PersonAdapter,
param_query,
variables,
QueryContext::default(),
).expect("Parameterized query failed");
println!("参数化查询结果: {:?}", param_results);
// 执行递归查询
let recurse_query = r#"
{
Person {
name @output
friends @recurse(depth: 2) {
name @output
}
}
}
"#;
let recurse_results = execute_query::<PersonAdapter>(
&schema,
PersonAdapter,
recurse_query,
std::collections::HashMap::new(),
QueryContext::default(),
).expect("Recursive query failed");
println!("递归查询结果: {:?}", recurse_results);
}
这个完整示例展示了:
- 定义Person数据模型和顶点类型
- 实现PersonAdapter适配器连接模拟数据
- 执行三种不同类型的查询:
- 基础查询:获取所有人的姓名、年龄和朋友列表
- 参数化查询:按姓名过滤查找特定人员
- 递归查询:递归查找朋友关系(深度为2)
您可以根据实际需求修改Person数据结构和适配器实现来连接真实数据源。