mirror of
https://github.com/tcsenpai/pensieve.git
synced 2025-06-06 19:25:24 +00:00
feat: support list latest content
This commit is contained in:
parent
57388edc22
commit
c31c89374a
@ -299,7 +299,7 @@ def touch_entity(entity_id: int, db: Session) -> bool:
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def update_entity_tags(entity_id: int, tags: List[str], db: Session) -> Entity:
|
def update_entity_tags(entity_id: int, tags: List[str], db: Session) -> Entity:
|
||||||
db_entity = get_entity_by_id(entity_id, db)
|
db_entity = get_entity_by_id(entity_id, db)
|
||||||
@ -453,20 +453,18 @@ def full_text_search(
|
|||||||
library_ids_str = ", ".join(f"'{id}'" for id in library_ids)
|
library_ids_str = ", ".join(f"'{id}'" for id in library_ids)
|
||||||
sql_query += f" AND entities.library_id IN ({library_ids_str})"
|
sql_query += f" AND entities.library_id IN ({library_ids_str})"
|
||||||
if start is not None and end is not None:
|
if start is not None and end is not None:
|
||||||
sql_query += (
|
sql_query += " AND strftime('%s', entities.file_created_at, 'utc') BETWEEN :start AND :end"
|
||||||
" AND strftime('%s', entities.file_created_at, 'utc') BETWEEN :start AND :end"
|
|
||||||
)
|
|
||||||
params["start"] = str(start)
|
params["start"] = str(start)
|
||||||
params["end"] = str(end)
|
params["end"] = str(end)
|
||||||
|
|
||||||
sql_query += " ORDER BY bm25(entities_fts) LIMIT :limit"
|
sql_query += " ORDER BY bm25(entities_fts), entities.last_scan_at DESC LIMIT :limit"
|
||||||
|
|
||||||
result = db.execute(text(sql_query), params).fetchall()
|
result = db.execute(text(sql_query), params).fetchall()
|
||||||
|
|
||||||
logger.info(f"Full-text search sql: {sql_query}")
|
logger.info(f"Full-text search sql: {sql_query}")
|
||||||
logger.info(f"Full-text search params: {params}")
|
logger.info(f"Full-text search params: {params}")
|
||||||
ids = [row[0] for row in result]
|
ids = [row[0] for row in result]
|
||||||
logger.debug(f"Full-text search results: {ids}")
|
logger.info(f"Full-text search results: {ids}")
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
|
||||||
@ -476,12 +474,12 @@ async def vec_search(
|
|||||||
limit: int = 200,
|
limit: int = 200,
|
||||||
library_ids: Optional[List[int]] = None,
|
library_ids: Optional[List[int]] = None,
|
||||||
start: Optional[int] = None,
|
start: Optional[int] = None,
|
||||||
end: Optional[int] = None
|
end: Optional[int] = None,
|
||||||
) -> List[int]:
|
) -> List[int]:
|
||||||
query_embedding = await get_embeddings([query])
|
query_embedding = await get_embeddings([query])
|
||||||
if not query_embedding:
|
if not query_embedding:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
query_embedding = query_embedding[0]
|
query_embedding = query_embedding[0]
|
||||||
|
|
||||||
sql_query = """
|
sql_query = """
|
||||||
@ -504,12 +502,12 @@ async def vec_search(
|
|||||||
params["start"] = str(start)
|
params["start"] = str(start)
|
||||||
params["end"] = str(end)
|
params["end"] = str(end)
|
||||||
|
|
||||||
sql_query += " AND K = :limit ORDER BY distance"
|
sql_query += " AND K = :limit ORDER BY distance, entities.last_scan_at DESC"
|
||||||
|
|
||||||
result = db.execute(text(sql_query), params).fetchall()
|
result = db.execute(text(sql_query), params).fetchall()
|
||||||
|
|
||||||
ids = [row[0] for row in result]
|
ids = [row[0] for row in result]
|
||||||
logger.debug(f"Vector search results: {ids}")
|
logger.info(f"Vector search results: {ids}")
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
|
||||||
@ -573,4 +571,28 @@ async def hybrid_search(
|
|||||||
total_time = end_time - start_time
|
total_time = end_time - start_time
|
||||||
logger.info(f"Total hybrid search time: {total_time:.4f} seconds")
|
logger.info(f"Total hybrid search time: {total_time:.4f} seconds")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
async def list_entities(
|
||||||
|
db: Session,
|
||||||
|
limit: int = 200,
|
||||||
|
library_ids: Optional[List[int]] = None,
|
||||||
|
start: Optional[int] = None,
|
||||||
|
end: Optional[int] = None,
|
||||||
|
) -> List[Entity]:
|
||||||
|
query = db.query(EntityModel).filter(EntityModel.file_type_group == "image")
|
||||||
|
|
||||||
|
if library_ids:
|
||||||
|
query = query.filter(EntityModel.library_id.in_(library_ids))
|
||||||
|
|
||||||
|
if start is not None and end is not None:
|
||||||
|
query = query.filter(
|
||||||
|
func.strftime("%s", EntityModel.file_created_at).between(
|
||||||
|
str(start), str(end)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
entities = query.order_by(EntityModel.last_scan_at.desc()).limit(limit).all()
|
||||||
|
|
||||||
|
return [Entity(**entity.__dict__) for entity in entities]
|
||||||
|
@ -782,9 +782,16 @@ async def search_entities_v2(
|
|||||||
library_ids = [int(id) for id in library_ids.split(",")] if library_ids else None
|
library_ids = [int(id) for id in library_ids.split(",")] if library_ids else None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
entities = await crud.hybrid_search(
|
if q.strip() == "":
|
||||||
query=q, db=db, limit=limit, library_ids=library_ids, start=start, end=end
|
# Use list_entities when q is empty
|
||||||
)
|
entities = await crud.list_entities(
|
||||||
|
db=db, limit=limit, library_ids=library_ids, start=start, end=end
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Use hybrid_search when q is not empty
|
||||||
|
entities = await crud.hybrid_search(
|
||||||
|
query=q, db=db, limit=limit, library_ids=library_ids, start=start, end=end
|
||||||
|
)
|
||||||
|
|
||||||
# Convert Entity list to SearchHit list
|
# Convert Entity list to SearchHit list
|
||||||
hits = []
|
hits = []
|
||||||
|
@ -242,6 +242,21 @@
|
|||||||
const enableScroll = () => {
|
const enableScroll = () => {
|
||||||
document.body.style.overflow = '';
|
document.body.style.overflow = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleEnterPress(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
event.preventDefault();
|
||||||
|
searchItems(
|
||||||
|
searchString,
|
||||||
|
startTimestamp,
|
||||||
|
endTimestamp,
|
||||||
|
selectedLibraries,
|
||||||
|
Object.keys(selectedTags).filter((tag) => selectedTags[tag]),
|
||||||
|
Object.keys(selectedDates).filter((date) => selectedDates[date]),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:keydown={handleKeydown} />
|
<svelte:window on:keydown={handleKeydown} />
|
||||||
@ -260,6 +275,7 @@
|
|||||||
class={inputClasses}
|
class={inputClasses}
|
||||||
bind:value={searchString}
|
bind:value={searchString}
|
||||||
placeholder="Type to search..."
|
placeholder="Type to search..."
|
||||||
|
on:keydown={handleEnterPress}
|
||||||
/>
|
/>
|
||||||
<div class="mx-auto max-w-screen-lg">
|
<div class="mx-auto max-w-screen-lg">
|
||||||
<div class="flex space-x-2" class:mt-4={!isScrolled} class:ml-4={isScrolled}>
|
<div class="flex space-x-2" class:mt-4={!isScrolled} class:ml-4={isScrolled}>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user