uqa_graph/operators/
vertex_match.rs1use super::{
10 BTreeMap, DocId, GraphPayload, GraphPostingList, GraphStore, GraphStoreError, GraphStoreResult,
11 Payload, PostingEntry, PostingList, VertexId, VertexPredicate, DEFAULT_GRAPH_SCORE,
12};
13
14pub struct VertexMatch<'a> {
17 pub graph: &'a str,
18 pub label: Option<&'a str>,
19 pub predicate: Option<VertexPredicate>,
20 pub score: f64,
21}
22
23impl<'a> VertexMatch<'a> {
24 pub fn new(graph: &'a str) -> Self {
25 Self {
26 graph,
27 label: None,
28 predicate: None,
29 score: DEFAULT_GRAPH_SCORE,
30 }
31 }
32
33 pub fn label(mut self, label: &'a str) -> Self {
34 self.label = Some(label);
35 self
36 }
37
38 pub fn predicate(mut self, p: VertexPredicate) -> Self {
39 self.predicate = Some(p);
40 self
41 }
42
43 pub fn execute<G: GraphStore>(&self, store: &G) -> GraphStoreResult<GraphPostingList> {
44 let candidates: Vec<VertexId> = match self.label {
45 Some(l) => store.vertex_ids_by_label(l, self.graph)?,
46 None => store.vertex_ids_in_graph(self.graph)?.into_iter().collect(),
47 };
48 let mut entries: Vec<PostingEntry> = Vec::new();
49 let mut graph_payloads: BTreeMap<DocId, GraphPayload> = BTreeMap::new();
50 for vid in candidates {
51 let vtx = store.get_vertex(vid).ok_or_else(|| {
52 GraphStoreError::CorruptGraph(format!("missing matched vertex {vid}"))
53 })?;
54 if let Some(pred) = &self.predicate {
55 if !pred.matches(vtx) {
56 continue;
57 }
58 }
59 entries.push(PostingEntry::new(vid, Payload::with_score(self.score)));
60 graph_payloads.insert(
61 vid,
62 GraphPayload {
63 subgraph_vertices: vec![vid],
64 subgraph_edges: Vec::new(),
65 graph_name: self.graph.to_string(),
66 score_override: Some(self.score),
67 },
68 );
69 }
70 entries.sort_by_key(|e| e.doc_id);
71 GraphPostingList::try_from_parts(
72 PostingList::from_sorted_unchecked(entries),
73 graph_payloads,
74 )
75 .map_err(Into::into)
76 }
77}
78
79