search crate compiled, lets get to fixing all the other errors

This commit is contained in:
filipriec
2025-06-08 20:10:57 +02:00
parent 2c7bda3ff1
commit b60e03eb70
7 changed files with 633 additions and 11 deletions

View File

@@ -1,14 +1,127 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
// src/lib.rs
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
use tantivy::{collector::TopDocs, query::QueryParser, Index, TantivyDocument};
use tantivy::schema::Value;
use tonic::{transport::Server, Request, Response, Status};
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
use common::proto::multieko2::search::{
search_response::Hit,
searcher_server::{Searcher, SearcherServer},
SearchRequest, SearchResponse,
};
pub struct SearcherService;
#[tonic::async_trait]
impl Searcher for SearcherService {
async fn search_table(
&self,
request: Request<SearchRequest>,
) -> Result<Response<SearchResponse>, Status> {
let req = request.into_inner();
let table_name = req.table_name;
let query_str = req.query;
if query_str.trim().is_empty() {
return Err(Status::invalid_argument("Query cannot be empty"));
}
// Open the index for this table
let index_path = Path::new("./tantivy_indexes").join(&table_name);
if !index_path.exists() {
return Err(Status::not_found(format!(
"No search index found for table '{}'",
table_name
)));
}
// Open the index
let index = Index::open_in_dir(&index_path).map_err(|e| {
Status::internal(format!("Failed to open index: {}", e))
})?;
// Create reader and searcher
let reader = index.reader().map_err(|e| {
Status::internal(format!("Failed to create index reader: {}", e))
})?;
let searcher = reader.searcher();
let schema = index.schema();
// Get the fields we need
let all_text_field = match schema.get_field("all_text") {
Ok(field) => field,
Err(_) => {
return Err(Status::internal(
"Schema is missing the 'all_text' field.",
))
}
};
let pg_id_field = match schema.get_field("pg_id") {
Ok(field) => field,
Err(_) => {
return Err(Status::internal(
"Schema is missing the 'pg_id' field.",
))
}
};
// Parse the query
let query_parser =
QueryParser::for_index(&index, vec![all_text_field]);
let query = query_parser.parse_query(&query_str).map_err(|e| {
Status::invalid_argument(format!("Invalid query: {}", e))
})?;
// Perform the search
let top_docs = searcher
.search(&query, &TopDocs::with_limit(100))
.map_err(|e| Status::internal(format!("Search failed: {}", e)))?;
// Convert results to our response format
let mut hits = Vec::new();
for (score, doc_address) in top_docs {
// FIX: Add explicit type TantivyDocument for the retrieved doc
let doc: TantivyDocument = searcher.doc(doc_address).map_err(
|e| {
Status::internal(format!(
"Failed to retrieve document: {}",
e
))
},
)?;
// Extract the PostgreSQL ID from the document
if let Some(pg_id_value) = doc.get_first(pg_id_field) {
if let Some(pg_id) = pg_id_value.as_u64() {
hits.push(Hit {
id: pg_id as i64,
score,
});
}
}
}
let response = SearchResponse { hits };
Ok(Response::new(response))
}
}
pub async fn run_search_service(
addr: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let addr = addr.parse()?;
let searcher_service = SearcherService;
println!("Search service listening on {}", addr);
Server::builder()
.add_service(SearcherServer::new(searcher_service))
.serve(addr)
.await?;
Ok(())
}