Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cheminee"
version = "0.1.9"
version = "0.1.10"
edition = "2021"
description = "Molecule indexing and search"
license = "MIT"
Expand Down
3 changes: 2 additions & 1 deletion src/rest_api/api/search/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
mod search;
mod substructure_search;

use poem_openapi::payload::Json;
use poem_openapi_derive::{ApiResponse, Object};
pub use search::*;
pub use substructure_search::*;
use tantivy::{DocAddress, Searcher};

Expand Down
68 changes: 68 additions & 0 deletions src/rest_api/api/search/search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use poem_openapi::payload::Json;
use poem_openapi_derive::{ApiResponse, Object};

use crate::{
indexing::index_manager::IndexManager,
rest_api::{
api::{aggregate_search_hits, GetStructureSearchResponse, StructureResponseError},
models::GenericResponseError,
},
search::{
compound_processing::{get_cpd_properties, get_tautomers},
prepare_query_structure,
substructure_search::substructure_search,
},
};

#[derive(ApiResponse)]
pub enum GetIndexesSearchResponse {
#[oai(status = "200")]
Ok(Json<Vec<SearchHit>>),
#[oai(status = "404")]
IndexDoesNotExist,
#[oai(status = "500")]
Err(Json<GenericResponseError>),
}

#[derive(Object, Debug)]
pub struct SearchHit {
pub error: String,
}

pub fn v1_index_search(
index_manager: &IndexManager,
index: String,
query: Option<String>,
limit: Option<usize>,
offset: Option<usize>,
) -> GetIndexesSearchResponse {
if !index_manager.exists(&index) {
return GetIndexesSearchResponse::IndexDoesNotExist;
}

let index = index_manager.open(&index);

let index = match index {
Ok(i) => i,
Err(e) => return GetIndexesSearchResponse::Err(Json(e.into())),
};

let query_parser = tantivy::query::QueryParser::for_index(&index, vec![]);
let schema = index.schema();

let reader = match index.reader() {
Ok(r) => r,
Err(e) => return GetIndexesSearchResponse::Err(e.into()),
};

let searcher = reader.searcher();

let query = query_parser.parse_query(query.as_deref().unwrap());
let query = match query {
Ok(q) => q,
Err(e) => return GetIndexesSearchResponse::Err(e.into()),
};

let collector = tantivy::collector::TopDocs::with_limit(1000)
searcher.search(&query)
}
19 changes: 19 additions & 0 deletions src/rest_api/models/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::error::Error;

use poem_openapi_derive::Object;

#[derive(Object, Debug)]
pub struct GenericResponseError {
pub error: String,
}

impl<T> From<T> for GenericResponseError
where
T: Error,
{
fn from(err: T) -> Self {
Self {
error: err.to_string(),
}
}
}
3 changes: 3 additions & 0 deletions src/rest_api/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod error;
pub use error::*;

mod smile;
pub use smile::*;
21 changes: 17 additions & 4 deletions src/rest_api/openapi_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ use crate::{
indexing::index_manager::IndexManager,
rest_api::{
api::{
v1_get_index, v1_index_search_substructure, v1_list_indexes, v1_list_schemas,
v1_post_index, v1_post_index_bulk, v1_standardize, BulkRequest, GetIndexesResponse,
GetStructureSearchResponse, ListIndexesResponse, ListSchemasResponse,
PostIndexResponse, PostIndexesBulkIndexResponse, StandardizeResponse,
v1_get_index, v1_index_search, v1_index_search_substructure, v1_list_indexes,
v1_list_schemas, v1_post_index, v1_post_index_bulk, v1_standardize, BulkRequest,
GetIndexesResponse, GetIndexesSearchResponse, GetStructureSearchResponse,
ListIndexesResponse, ListSchemasResponse, PostIndexResponse,
PostIndexesBulkIndexResponse, StandardizeResponse,
},
models::Smile,
},
Expand Down Expand Up @@ -136,6 +137,18 @@ impl Api {
v1_post_index_bulk(&self.index_manager, index.to_string(), bulk_request.0).await
}

#[oai(path = "/v1/indexes/:index/search", method = "get")]
/// The no-smarts search, just applies a tantivy query to the index and serializes the response
pub async fn v1_index_search(
&self,
index: Path<String>,
q: Query<Option<String>>,
limit: Query<Option<usize>>,
offset: Query<Option<usize>>,
) -> GetIndexesSearchResponse {
v1_index_search(&self.index_manager, index.to_string, q.0, offset.0)
}

#[oai(path = "/v1/indexes/:index/search/substructure", method = "get")]
/// Perform substructure search against index
pub async fn v1_index_search_substructure(
Expand Down