Release v1.0.0 candidate

This commit is contained in:
Accusys
2026-05-08 00:48:15 +08:00
parent 26d9c33419
commit 573714788f
17 changed files with 5040 additions and 895 deletions

View File

@@ -1241,7 +1241,7 @@ impl PostgresDb {
.execute(&self.pool)
.await?;
sqlx::query(&format!("DELETE FROM {} WHERE uuid = $1", chunks))
sqlx::query(&format!("DELETE FROM {} WHERE file_uuid = $1", chunks))
.bind(uuid)
.execute(&self.pool)
.await?;
@@ -1279,7 +1279,7 @@ impl PostgresDb {
pub async fn get_chunk_count(&self, uuid: &str) -> Result<(i64, i64)> {
let chunks = schema::table_name("chunks");
let sentence_count: i64 = sqlx::query_scalar(&format!(
"SELECT COUNT(*) FROM {} WHERE uuid = $1 AND chunk_type = 'sentence'",
"SELECT COUNT(*) FROM {} WHERE file_uuid = $1 AND chunk_type = 'sentence'",
chunks
))
.bind(uuid)
@@ -1287,7 +1287,7 @@ impl PostgresDb {
.await?;
let time_count: i64 = sqlx::query_scalar(&format!(
"SELECT COUNT(*) FROM {} WHERE uuid = $1 AND chunk_type = 'time_based'",
"SELECT COUNT(*) FROM {} WHERE file_uuid = $1 AND chunk_type = 'time_based'",
chunks
))
.bind(uuid)
@@ -2567,9 +2567,9 @@ impl PostgresDb {
sqlx::query(&format!(
r#"
INSERT INTO {} (file_id, file_uuid, chunk_id, chunk_index, chunk_type, start_time, end_time, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id, child_chunk_ids)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12::jsonb, $13::jsonb, $14, $15, $16, $17, $18)
ON CONFLICT (file_uuid, chunk_id) DO UPDATE SET
INSERT INTO {} (file_id, file_uuid, chunk_id, old_chunk_id, chunk_index, chunk_type, start_time, end_time, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id, child_chunk_ids)
VALUES ($1, $2, $3, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12::jsonb, $13::jsonb, $14, $15, $16, $17, $18)
ON CONFLICT (file_uuid, old_chunk_id) DO UPDATE SET
start_time = EXCLUDED.start_time,
end_time = EXCLUDED.end_time,
fps = EXCLUDED.fps,
@@ -2642,9 +2642,9 @@ impl PostgresDb {
sqlx::query(&format!(
r#"
INSERT INTO {} (file_id, file_uuid, chunk_id, chunk_index, chunk_type, start_time, end_time, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id, child_chunk_ids)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12::jsonb, $13::jsonb, $14, $15, $16, $17, $18)
ON CONFLICT (file_uuid, chunk_id) DO UPDATE SET
INSERT INTO {} (file_id, file_uuid, chunk_id, old_chunk_id, chunk_index, chunk_type, start_time, end_time, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id, child_chunk_ids)
VALUES ($1, $2, $3, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12::jsonb, $13::jsonb, $14, $15, $16, $17, $18)
ON CONFLICT (file_uuid, old_chunk_id) DO UPDATE SET
start_time = EXCLUDED.start_time,
end_time = EXCLUDED.end_time,
fps = EXCLUDED.fps,
@@ -4453,7 +4453,7 @@ impl PostgresDb {
COUNT(*) as chunks_count,
COALESCE(SUM(end_frame - start_frame), 0) as chunks_frames
FROM {}
WHERE uuid = $1
WHERE file_uuid = $1
"#,
chunks_table
))
@@ -4720,7 +4720,7 @@ impl PostgresDb {
1 - (embedding <=> $1::vector) as similarity,
bbox
FROM {}
WHERE file_uuid = $2
WHERE uuid = $2
AND embedding IS NOT NULL
AND 1 - (embedding <=> $1::vector) >= $3
ORDER BY embedding <=> $1::vector

View File

@@ -88,6 +88,44 @@ impl QdrantDb {
Ok(())
}
/// 確保指定 collection 存在,不存在則自動建立
pub async fn ensure_collection(&self, collection: &str, vector_dim: usize) -> Result<()> {
let url = format!("{}/collections/{}", self.base_url, collection);
let exists = self
.client
.get(&url)
.header("api-key", &self.api_key)
.send()
.await
.map(|r| r.status().is_success())
.unwrap_or(false);
if exists {
return Ok(());
}
let create_url = format!("{}/collections", self.base_url);
let body = serde_json::json!({
"vectors": {
"size": vector_dim,
"distance": "Cosine"
}
});
self.client
.post(&create_url)
.header("api-key", &self.api_key)
.header("Content-Type", "application/json")
.json(&body)
.send()
.await
.context(format!("Failed to create Qdrant collection: {}", collection))?;
tracing::info!("Created Qdrant collection: {} (dim={})", collection, vector_dim);
Ok(())
}
/// 將向量寫入指定 collection支援多 collection
pub async fn upsert_vector_to_collection(
&self,
@@ -687,14 +725,13 @@ pub async fn sync_face_embeddings(file_uuid: &str) -> Result<()> {
use sqlx::Row;
let pool = sqlx::PgPool::connect(&DATABASE_URL).await?;
let schema = crate::core::config::DATABASE_SCHEMA.as_str();
let table = crate::core::db::schema::table_name("face_detections");
let qdrant: QdrantDb = QdrantDb::new();
let query = format!(
"SELECT id, trace_id, frame_number, embedding FROM {}.{} WHERE file_uuid = $1 AND embedding IS NOT NULL",
schema, table
"SELECT id, trace_id, frame_number, embedding FROM {} WHERE file_uuid = $1 AND embedding IS NOT NULL",
table
);
let rows = sqlx::query(&query).bind(file_uuid).fetch_all(&pool).await?;