Execute a query plan against a repository.
(repo: &Repository, plan: &QueryPlan)
| 141 | |
| 142 | /// Execute a query plan against a repository. |
| 143 | pub fn execute_plan(repo: &Repository, plan: &QueryPlan) -> Result<PlanResult, RepositoryError> { |
| 144 | let overall_start = std::time::Instant::now(); |
| 145 | |
| 146 | let mut bindings: HashMap<String, Vec<KgNode>> = HashMap::new(); |
| 147 | let mut all_nodes: Vec<KgNode> = Vec::new(); |
| 148 | let mut all_edges: Vec<KgEdge> = Vec::new(); |
| 149 | let mut content: HashMap<String, String> = HashMap::new(); |
| 150 | let mut step_stats: Vec<StepStat> = Vec::new(); |
| 151 | |
| 152 | for step in &plan.steps { |
| 153 | let step_start = std::time::Instant::now(); |
| 154 | |
| 155 | match step { |
| 156 | QueryStep::KgSearch { query, limit, bind } => { |
| 157 | let nodes = repo.vault_kg_search(query, *limit, None)?; |
| 158 | let count = nodes.len(); |
| 159 | |
| 160 | if let Some(var) = bind { |
| 161 | bindings.insert(var.clone(), nodes.clone()); |
| 162 | } |
| 163 | all_nodes.extend(nodes); |
| 164 | |
| 165 | step_stats.push(StepStat { |
| 166 | step_type: "kg_search".to_string(), |
| 167 | result_count: count, |
| 168 | elapsed_ms: step_start.elapsed().as_millis() as u64, |
| 169 | }); |
| 170 | } |
| 171 | |
| 172 | QueryStep::KgNeighbors { |
| 173 | node_id, |
| 174 | depth, |
| 175 | bind, |
| 176 | } => { |
| 177 | // Resolve $variable references |
| 178 | let ids = resolve_node_ids(node_id, &bindings); |
| 179 | |
| 180 | let mut step_nodes = Vec::new(); |
| 181 | let mut step_edges = Vec::new(); |
| 182 | |
| 183 | for id in &ids { |
| 184 | match repo.vault_kg_neighbors(id, *depth) { |
| 185 | Ok(sg) => { |
| 186 | step_nodes.extend(sg.nodes); |
| 187 | step_edges.extend(sg.edges); |
| 188 | } |
| 189 | Err(e) => { |
| 190 | log::warn!("KG neighbors failed for {}: {}", id, e); |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | let count = step_nodes.len(); |
| 196 | if let Some(var) = bind { |
| 197 | bindings.insert(var.clone(), step_nodes.clone()); |
| 198 | } |
| 199 | all_nodes.extend(step_nodes); |
| 200 | all_edges.extend(step_edges); |