Ensure the reverse FTS index exists and rebuild both directions once for databases created before replacement-safe indexing was introduced.
(&mut self)
| 28 | /// Ensure the reverse FTS index exists and rebuild both directions once for |
| 29 | /// databases created before replacement-safe indexing was introduced. |
| 30 | fn ensure_kg_fts_schema(&mut self) -> PristineResult<()> { |
| 31 | self.txn.open_multimap_table(KG_FTS)?; |
| 32 | self.txn.open_multimap_table(KG_FTS_BY_NODE)?; |
| 33 | |
| 34 | let current_version = { |
| 35 | let metadata = self.txn.open_table(KG_INDEX_META)?; |
| 36 | let stored_version = metadata.get(KG_FTS_REVERSE_SCHEMA_KEY)?; |
| 37 | match stored_version { |
| 38 | Some(value) => value.value(), |
| 39 | None => 0, |
| 40 | } |
| 41 | }; |
| 42 | if current_version >= KG_FTS_REVERSE_SCHEMA_VERSION { |
| 43 | return Ok(()); |
| 44 | } |
| 45 | |
| 46 | // Legacy KG FTS only ever appended postings. Rebuild from KG_NODES so |
| 47 | // both orphan postings and obsolete label/summary tokens disappear. |
| 48 | let nodes_to_index = { |
| 49 | let nodes = self.txn.open_table(KG_NODES)?; |
| 50 | let mut indexed = Vec::new(); |
| 51 | for entry in nodes.iter()? { |
| 52 | let (node_id, node_bytes) = entry?; |
| 53 | let node: KgNode = serde_json::from_slice(node_bytes.value()).map_err(|e| { |
| 54 | PristineError::Serialization { |
| 55 | message: e.to_string(), |
| 56 | } |
| 57 | })?; |
| 58 | let tokens: std::collections::HashSet<String> = |
| 59 | tokenize_for_fts(&kg_node_fts_text(&node)) |
| 60 | .into_iter() |
| 61 | .collect(); |
| 62 | indexed.push((node_id.value().to_string(), tokens)); |
| 63 | } |
| 64 | indexed |
| 65 | }; |
| 66 | |
| 67 | let forward_keys = { |
| 68 | let fts = self.txn.open_multimap_table(KG_FTS)?; |
| 69 | let mut keys = Vec::new(); |
| 70 | for entry in fts.iter()? { |
| 71 | keys.push(entry?.0.value().to_string()); |
| 72 | } |
| 73 | keys |
| 74 | }; |
| 75 | { |
| 76 | let mut fts = self.txn.open_multimap_table(KG_FTS)?; |
| 77 | for token in forward_keys { |
| 78 | fts.remove_all(token.as_str())?; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | let reverse_keys = { |
| 83 | let reverse = self.txn.open_multimap_table(KG_FTS_BY_NODE)?; |
| 84 | let mut keys = Vec::new(); |
| 85 | for entry in reverse.iter()? { |
| 86 | keys.push(entry?.0.value().to_string()); |
| 87 | } |
no test coverage detected