diff --git a/memos/crud.py b/memos/crud.py index 0e5ade1..9006807 100644 --- a/memos/crud.py +++ b/memos/crud.py @@ -299,7 +299,7 @@ def touch_entity(entity_id: int, db: Session) -> bool: return True else: return False - + def update_entity_tags(entity_id: int, tags: List[str], db: Session) -> Entity: 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) sql_query += f" AND entities.library_id IN ({library_ids_str})" if start is not None and end is not None: - sql_query += ( - " AND strftime('%s', entities.file_created_at, 'utc') BETWEEN :start AND :end" - ) + sql_query += " AND strftime('%s', entities.file_created_at, 'utc') BETWEEN :start AND :end" params["start"] = str(start) 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() logger.info(f"Full-text search sql: {sql_query}") logger.info(f"Full-text search params: {params}") 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 @@ -476,12 +474,12 @@ async def vec_search( limit: int = 200, library_ids: Optional[List[int]] = None, start: Optional[int] = None, - end: Optional[int] = None + end: Optional[int] = None, ) -> List[int]: query_embedding = await get_embeddings([query]) if not query_embedding: return [] - + query_embedding = query_embedding[0] sql_query = """ @@ -504,12 +502,12 @@ async def vec_search( params["start"] = str(start) 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() ids = [row[0] for row in result] - logger.debug(f"Vector search results: {ids}") + logger.info(f"Vector search results: {ids}") return ids @@ -573,4 +571,28 @@ async def hybrid_search( total_time = end_time - start_time logger.info(f"Total hybrid search time: {total_time:.4f} seconds") - return result \ No newline at end of file + 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] diff --git a/memos/server.py b/memos/server.py index 3f1f708..02e29a7 100644 --- a/memos/server.py +++ b/memos/server.py @@ -782,9 +782,16 @@ async def search_entities_v2( library_ids = [int(id) for id in library_ids.split(",")] if library_ids else None try: - entities = await crud.hybrid_search( - query=q, db=db, limit=limit, library_ids=library_ids, start=start, end=end - ) + if q.strip() == "": + # 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 hits = [] diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 401788c..7d61ebd 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -242,6 +242,21 @@ const enableScroll = () => { 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 + ); + } + } @@ -260,6 +275,7 @@ class={inputClasses} bind:value={searchString} placeholder="Type to search..." + on:keydown={handleEnterPress} />