Rust JSON路径查询库serde_json_path_core的使用,高效解析与操作JSON数据结构的核心功能

Rust JSON路径查询库serde_json_path_core的使用,高效解析与操作JSON数据结构的核心功能

serde_json_path_core是serde_json_path crate的核心类型库,用于高效解析和操作JSON数据结构。

安装

在项目目录中运行以下Cargo命令:

cargo add serde_json_path_core

或者在Cargo.toml中添加以下行:

serde_json_path_core = "0.2.2"

基本使用示例

以下是一个使用serde_json_path_core进行JSON路径查询的完整示例:

use serde_json::json;
use serde_json_path::{JsonPath, NodeList};

fn main() {
    // 创建一个示例JSON数据
    let data = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                },
                {
                    "category": "fiction",
                    "author": "Herman Melville",
                    "title": "Moby Dick",
                    "isbn": "0-553-21311-3",
                    "price": 8.99
                },
                {
                    "category": "fiction",
                    "author": "J. R. R. Tolkien",
                    "title": "The Lord of the Rings",
                    "isbn": "0-395-19395-8",
                    "price": 22.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        }
    });

    // 创建JSON路径查询
    let path = JsonPath::parse("$.store.book[*].author").unwrap();
    
    // 执行查询
    let authors = path.query(&data).all();
    
    // 输出结果
    println!("所有作者:");
    for author in authors {
        println!("- {}", author.as_str().unwrap());
    }
    
    // 另一个查询示例:查找价格低于10的书籍
    let cheap_books_path = JsonPath::parse("$.store.book[?(@.price < 10)]").unwrap();
    let cheap_books = cheap_books_path.query(&data).all();
    
    println!("\n价格低于10的书籍:");
    for book in cheap_books {
        println!("- {} (价格: {})", 
            book["title"].as_str().unwrap(), 
            book["price"].as_f64().unwrap());
    }
}

核心功能

  1. JSON路径解析:支持标准的JSON路径语法
  2. 高效查询:快速定位JSON数据结构中的特定节点
  3. 条件过滤:支持使用表达式过滤结果
  4. 多结果处理:可以获取单个结果或多个结果

高级用法示例

use serde_json::json;
use serde_json_path::{JsonPath, NodeList};

fn main() {
    let data = json!({
        "employees": [
            {
                "id": 1,
                "name": "John",
                "department": "IT",
                "salary": 75000,
                "skills": ["Rust", "Python", "JavaScript"]
            },
            {
                "id": 2,
                "name": "Jane",
                "department": "HR",
                "salary": 65000,
                "skills": ["Communication", "Recruiting"]
            },
            {
                "id": 3,
                "name": "Bob",
                "department": "IT",
                "salary": 80000,
                "skills": ["Rust", "Go", "System Design"]
            }
        ]
    });

    // 查询IT部门的所有员工
    let it_employees = JsonPath::parse("$.employees[?(@.department == 'IT')]")
        .unwrap()
        .query(&data)
        .all();
    
    println!("IT部门员工:");
    for emp in it_employees {
        println!("- {} (ID: {})", 
            emp["name"].as_str().unwrap(),
            emp["id"].as_i64().unwrap());
    }

    // 查询掌握Rust技能的员工
    let rust_devs = JsonPath::parse("$.employees[?('Rust' in @.skills)]")
        .unwrap()
        .query(&data)
        .all();
    
    println!("\n掌握Rust技能的员工:");
    for dev in rust_devs {
        println!("- {}", dev["name"].as_str().unwrap());
    }

    // 使用函数计算平均薪资
    let salaries: Vec<f64> = JsonPath::parse("$.employees[*].salary")
        .unwrap()
        .query(&data)
        .all()
        .iter()
        .map(|v| v.as_f64().unwrap())
        .collect();
    
    let avg_salary: f64 = salaries.iter().sum::<f64>() / salaries.len() as f64;
    println!("\n平均薪资: {:.2}", avg_salary);
}

完整示例代码

以下是一个结合基本使用和高级用法的完整示例:

use serde_json::json;
use serde_json_path::{JsonPath, NodeList};

fn main() {
    // 创建复杂的JSON数据结构
    let data = json!({
        "company": {
            "name": "TechCorp",
            "departments": {
                "engineering": {
                    "employees": [
                        {
                            "id": 101,
                            "name": "Alice",
                            "position": "Senior Developer",
                            "skills": ["Rust", "C++", "Distributed Systems"],
                            "projects": [
                                {
                                    "name": "Cloud Storage",
                                    "tech_stack": ["Rust", "AWS"],
                                    "budget": 150000.0
                                },
                                {
                                    "name": "Data Pipeline",
                                    "tech_stack": ["Python", "Kafka"],
                                    "budget": 120000.0
                                }
                            ]
                        },
                        {
                            "id": 102,
                            "name": "Bob",
                            "position": "DevOps Engineer",
                            "skills": ["Kubernetes", "AWS", "Terraform"],
                            "projects": [
                                {
                                    "name": "CI/CD System",
                                    "tech_stack": ["Jenkins", "Docker"],
                                    "budget": 80000.0
                                }
                            ]
                        }
                    ]
                },
                "marketing": {
                    "employees": [
                        {
                            "id": 201,
                            "name": "Carol",
                            "position": "Marketing Manager",
                            "skills": ["SEO", "Content Strategy"],
                            "campaigns": [
                                {
                                    "name": "Product Launch",
                                    "budget": 50000.0,
                                    "channels": ["Social Media", "Email"]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    });

    // 示例1: 查询所有使用Rust的项目
    let rust_projects = JsonPath::parse("$..projects[?('Rust' in @.tech_stack)]")
        .unwrap()
        .query(&data)
        .all();
    
    println!("使用Rust技术的项目:");
    for project in rust_projects {
        println!("- {} (预算: {:.2})", 
            project["name"].as_str().unwrap(),
            project["budget"].as_f64().unwrap());
    }

    // 示例2: 查询预算超过10万的项目
    let high_budget_projects = JsonPath::parse("$..projects[?(@.budget > 100000)]")
        .unwrap()
        .query(&data)
        .all();
    
    println!("\n高预算项目:");
    for project in high_budget_projects {
        println!("- {} (预算: {:.2}, 技术栈: {:?})", 
            project["name"].as_str().unwrap(),
            project["budget"].as_f64().unwrap(),
            project["tech_stack"].as_array().unwrap());
    }

    // 示例3: 查询工程部门的所有员工姓名
    let eng_employees = JsonPath::parse("$.company.departments.engineering.employees[*].name")
        .unwrap()
        .query(&data)
        .all();
    
    println!("\n工程部门员工:");
    for emp in eng_employees {
        println!("- {}", emp.as_str().unwrap());
    }

    // 示例4: 复杂条件查询 - 使用AWS且预算超过10万的项目
    let complex_query = JsonPath::parse("$..projects[?('AWS' in @.tech_stack && @.budget > 100000)]")
        .unwrap()
        .query(&data)
        .all();
    
    println!("\n使用AWS且预算超过10万的项目:");
    for project in complex_query {
        println!("- {}", project["name"].as_str().unwrap());
    }
}

serde_json_path_core提供了强大的JSON数据处理能力,可以高效地查询和操作复杂的JSON结构。


1 回复

Rust JSON路径查询库serde_json_path_core使用指南

serde_json_path_core是一个用于高效查询和操作JSON数据的Rust库,它实现了JSONPath语法,可以方便地从复杂的JSON结构中提取数据。

主要特性

  • 支持标准的JSONPath语法
  • 高性能的JSON数据查询
  • serde_json无缝集成
  • 支持多种查询操作

基本使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
serde_json = "1.0"
serde_json_path = "0.3"

基本查询示例

use serde_json::{json, Value};
use serde_json_path::JsonPath;

fn main() {
    // 示例JSON数据
    let data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        }
    });

    // 创建JSONPath表达式
    let path = JsonPath::parse("$.store.book[*].author").unwrap();
    
    // 执行查询
    let authors = path.query(&data).all();
    
    println!("Authors: {:?}", authors);
    // 输出: Authors: ["Nigel Rees", "Evelyn Waugh"]
}

高级用法

1. 条件过滤

let path = JsonPath::parse("$.store.book[?(@.price > 10)].title").unwrap();
let expensive_books = path.query(&data).all();
println!("Expensive books: {:?}", expensive_books);
// 输出: Expensive books: ["Sword of Honour"]

2. 多路径查询

let path = JsonPath::parse("$.store.book[0,1].price").unwrap();
let prices = path.query(&data).all();
println!("Prices: {:?}", prices);
// 输出: Prices: [8.95, 12.99]

3. 递归搜索

let path = JsonPath::parse("$..price").unwrap();
let all_prices = path.query(&data).all();
println!("All prices: {:?}", all_prices);
// 输出: All prices: [8.95, 12.99, 19.95]

4. 修改数据

use serde_json_path::NodeMut;

let mut data = data.clone();
let path = JsonPath::parse("$.store.book[0].price").unwrap();

if let Some(NodeMut::Value(value)) = path.query_mut(&mut data).first() {
    *value = json!(9.95);
}

println!("Modified data: {}", data);

性能提示

  1. 对于重复使用的JSONPath表达式,建议提前编译并复用JsonPath实例
  2. 对于大型JSON文档,考虑使用query_mut进行原地修改而不是创建新副本
  3. 如果只需要第一个匹配结果,使用first()而不是all()可以提高性能

错误处理

match JsonPath::parse("$.invalid.path[") {
    Ok(path) => {
        // 查询逻辑
    }
    Err(e) => {
        eprintln!("Invalid JSONPath expression: {}", e);
    }
}

完整示例代码

use serde_json::{json, Value};
use serde_json_path::{JsonPath, NodeMut};

fn main() {
    // 1. 基本查询示例
    basic_query_example();
    
    // 2. 条件过滤示例
    filter_example();
    
    // 3. 多路径查询示例
    multi_path_example();
    
    // 4. 递归搜索示例
    recursive_search_example();
    
    // 5. 修改数据示例
    modify_data_example();
    
    // 6. 错误处理示例
    error_handling_example();
}

fn basic_query_example() {
    println!("=== 基本查询示例 ===");
    let data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        }
    });

    let path = JsonPath::parse("$.store.book[*].author").unwrap();
    let authors = path.query(&data).all();
    println!("Authors: {:?}\n", authors);
}

fn filter_example() {
    println!("=== 条件过滤示例 ===");
    let data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ]
        }
    });

    let path = JsonPath::parse("$.store.book[?(@.price > 10)].title").unwrap();
    let expensive_books = path.query(&data).all();
    println!("Expensive books: {:?}\n", expensive_books);
}

fn multi_path_example() {
    println!("=== 多路径查询示例 ===");
    let data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ]
        }
    });

    let path = JsonPath::parse("$.store.book[0,1].price").unwrap();
    let prices = path.query(&data).all();
    println!("Prices: {:?}\n", prices);
}

fn recursive_search_example() {
    println!("=== 递归搜索示例 ===");
    let data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        }
    });

    let path = JsonPath::parse("$..price").unwrap();
    let all_prices = path.query(&data).all();
    println!("All prices: {:?}\n", all_prices);
}

fn modify_data_example() {
    println!("=== 修改数据示例 ===");
    let mut data: Value = json!({
        "store": {
            "book": [
                {
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                }
            ]
        }
    });

    let path = JsonPath::parse("$.store.book[0].price").unwrap();
    
    if let Some(NodeMut::Value(value)) = path.query_mut(&mut data).first() {
        *value = json!(9.95);
    }

    println!("Modified data: {}\n", data);
}

fn error_handling_example() {
    println!("=== 错误处理示例 ===");
    match JsonPath::parse("$.invalid.path[") {
        Ok(path) => {
            println!("Valid path: {:?}", path);
        }
        Err(e) => {
            eprintln!("Invalid JSONPath expression: {}\n", e);
        }
    }
}

这个完整示例演示了serde_json_path_core库的主要功能,包括基本查询、条件过滤、多路径查询、递归搜索、数据修改和错误处理。每个功能都有独立的函数实现,方便理解和测试。

回到顶部