mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-18 06:59:43 +02:00
feat: quick search knowledge entities
This commit is contained in:
@@ -6,9 +6,11 @@ use axum::{
|
||||
};
|
||||
use common::storage::types::{
|
||||
conversation::Conversation,
|
||||
knowledge_entity::{KnowledgeEntity, KnowledgeEntitySearchResult},
|
||||
text_content::{TextContent, TextContentSearchResult},
|
||||
user::User,
|
||||
};
|
||||
use futures::future::try_join;
|
||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
|
||||
use crate::{
|
||||
@@ -43,9 +45,19 @@ pub async fn search_result_handler(
|
||||
Query(params): Query<SearchParams>,
|
||||
RequireUser(user): RequireUser,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
#[derive(Serialize)]
|
||||
struct SearchResultForTemplate {
|
||||
result_type: String,
|
||||
score: f32,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
text_content: Option<TextContentSearchResult>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
knowledge_entity: Option<KnowledgeEntitySearchResult>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct AnswerData {
|
||||
search_result: Vec<TextContentSearchResult>,
|
||||
search_result: Vec<SearchResultForTemplate>,
|
||||
query_param: String,
|
||||
user: User,
|
||||
conversation_archive: Vec<Conversation>,
|
||||
@@ -56,17 +68,45 @@ pub async fn search_result_handler(
|
||||
if let Some(actual_query) = params.query {
|
||||
let trimmed_query = actual_query.trim();
|
||||
if trimmed_query.is_empty() {
|
||||
(Vec::new(), String::new())
|
||||
(Vec::<SearchResultForTemplate>::new(), String::new())
|
||||
} else {
|
||||
match TextContent::search(&state.db, trimmed_query, &user.id, 5).await {
|
||||
Ok(results) => (results, trimmed_query.to_string()),
|
||||
Err(e) => {
|
||||
return Err(HtmlError::from(e));
|
||||
}
|
||||
const TOTAL_LIMIT: usize = 10;
|
||||
let (text_results, entity_results) = try_join(
|
||||
TextContent::search(&state.db, trimmed_query, &user.id, TOTAL_LIMIT),
|
||||
KnowledgeEntity::search(&state.db, trimmed_query, &user.id, TOTAL_LIMIT),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut combined_results: Vec<SearchResultForTemplate> =
|
||||
Vec::with_capacity(text_results.len() + entity_results.len());
|
||||
|
||||
for text_result in text_results {
|
||||
let score = text_result.score;
|
||||
combined_results.push(SearchResultForTemplate {
|
||||
result_type: "text_content".to_string(),
|
||||
score,
|
||||
text_content: Some(text_result),
|
||||
knowledge_entity: None,
|
||||
});
|
||||
}
|
||||
|
||||
for entity_result in entity_results {
|
||||
let score = entity_result.score;
|
||||
combined_results.push(SearchResultForTemplate {
|
||||
result_type: "knowledge_entity".to_string(),
|
||||
score,
|
||||
text_content: None,
|
||||
knowledge_entity: Some(entity_result),
|
||||
});
|
||||
}
|
||||
|
||||
combined_results.sort_by(|a, b| b.score.total_cmp(&a.score));
|
||||
combined_results.truncate(TOTAL_LIMIT);
|
||||
|
||||
(combined_results, trimmed_query.to_string())
|
||||
}
|
||||
} else {
|
||||
(Vec::new(), String::new())
|
||||
(Vec::<SearchResultForTemplate>::new(), String::new())
|
||||
};
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
|
||||
Reference in New Issue
Block a user