From df4b07d29cc9f5b441d6543269673541a210c2b7 Mon Sep 17 00:00:00 2001 From: hyungi Date: Tue, 16 Jun 2026 14:28:33 +0900 Subject: [PATCH] =?UTF-8?q?refactor(library):=20facet-counts=204=EB=B8=94?= =?UTF-8?q?=EB=A1=9D=20=ED=97=AC=ED=8D=BC=20=EC=B6=94=EC=B6=9C=20=E2=80=94?= =?UTF-8?q?=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0=20(R10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit company/topic/year/doctype 4 facet 집계 블록이 거의 동일 복붙(각 base_query 재구성 + 다른 3축 필터 적용). 적용된 facet 필터를 applied dict 로 모으고 '자기 자신 축 제외' 헬퍼 _facet_count(name, col, order_by, value_fn)로 추출 — 쿼리/자기제외/order_by(year=desc·others=count)/ value 매핑(year=str) 모두 동일 보존. 동작 무변경(staging 에서 facet 카운트 동등성 확인 권장). 검증: py_compile 통과. Co-Authored-By: Claude Opus 4.8 (1M context) --- app/api/library.py | 91 ++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 64 deletions(-) diff --git a/app/api/library.py b/app/api/library.py index fd201a6..a0137d7 100644 --- a/app/api/library.py +++ b/app/api/library.py @@ -473,72 +473,35 @@ async def get_facet_counts( result = FacetCountsResponse(company=[], topic=[], year=[], doctype=[]) - # company counts (다른 facet 필터 적용, 자기 자신 제외) - q_company = base_query() - if facet_topic: - q_company = q_company.where(Document.facet_topic == facet_topic) - if facet_year: - q_company = q_company.where(Document.facet_year == facet_year) - if facet_doctype: - q_company = q_company.where(Document.facet_doctype == facet_doctype) - rows = await session.execute( - select(Document.facet_company, func.count()) - .where(Document.facet_company != None) # noqa: E711 - .where(Document.id.in_(q_company.with_only_columns(Document.id).subquery().select())) - .group_by(Document.facet_company) - .order_by(func.count().desc()) - ) - result.company = [FacetCountItem(value=r[0], count=r[1]) for r in rows] - - # topic counts - q_topic = base_query() + # R10: 4 facet 블록 중복 제거 — 적용된 facet 필터(값 있는 것만)를 모아 각 축 집계 시 + # '자기 자신 축'만 제외하고 적용하는 헬퍼로. 쿼리/자기제외/order_by/value 매핑 모두 동일. + applied: dict = {} if facet_company: - q_topic = q_topic.where(Document.facet_company == facet_company) - if facet_year: - q_topic = q_topic.where(Document.facet_year == facet_year) - if facet_doctype: - q_topic = q_topic.where(Document.facet_doctype == facet_doctype) - rows = await session.execute( - select(Document.facet_topic, func.count()) - .where(Document.facet_topic != None) # noqa: E711 - .where(Document.id.in_(q_topic.with_only_columns(Document.id).subquery().select())) - .group_by(Document.facet_topic) - .order_by(func.count().desc()) - ) - result.topic = [FacetCountItem(value=r[0], count=r[1]) for r in rows] - - # year counts - q_year = base_query() - if facet_company: - q_year = q_year.where(Document.facet_company == facet_company) + applied["company"] = Document.facet_company == facet_company if facet_topic: - q_year = q_year.where(Document.facet_topic == facet_topic) - if facet_doctype: - q_year = q_year.where(Document.facet_doctype == facet_doctype) - rows = await session.execute( - select(Document.facet_year, func.count()) - .where(Document.facet_year != None) # noqa: E711 - .where(Document.id.in_(q_year.with_only_columns(Document.id).subquery().select())) - .group_by(Document.facet_year) - .order_by(Document.facet_year.desc()) - ) - result.year = [FacetCountItem(value=str(r[0]), count=r[1]) for r in rows] - - # doctype counts - q_doctype = base_query() - if facet_company: - q_doctype = q_doctype.where(Document.facet_company == facet_company) - if facet_topic: - q_doctype = q_doctype.where(Document.facet_topic == facet_topic) + applied["topic"] = Document.facet_topic == facet_topic if facet_year: - q_doctype = q_doctype.where(Document.facet_year == facet_year) - rows = await session.execute( - select(Document.facet_doctype, func.count()) - .where(Document.facet_doctype != None) # noqa: E711 - .where(Document.id.in_(q_doctype.with_only_columns(Document.id).subquery().select())) - .group_by(Document.facet_doctype) - .order_by(func.count().desc()) - ) - result.doctype = [FacetCountItem(value=r[0], count=r[1]) for r in rows] + applied["year"] = Document.facet_year == facet_year + if facet_doctype: + applied["doctype"] = Document.facet_doctype == facet_doctype + + async def _facet_count(name, facet_col, order_by, value_fn): + q = base_query() + for k, cond in applied.items(): + if k != name: # 자기 자신 facet 필터는 제외 (다른 축만 적용) + q = q.where(cond) + rows = await session.execute( + select(facet_col, func.count()) + .where(facet_col != None) # noqa: E711 + .where(Document.id.in_(q.with_only_columns(Document.id).subquery().select())) + .group_by(facet_col) + .order_by(order_by) + ) + return [FacetCountItem(value=value_fn(r[0]), count=r[1]) for r in rows] + + result.company = await _facet_count("company", Document.facet_company, func.count().desc(), lambda v: v) + result.topic = await _facet_count("topic", Document.facet_topic, func.count().desc(), lambda v: v) + result.year = await _facet_count("year", Document.facet_year, Document.facet_year.desc(), lambda v: str(v)) + result.doctype = await _facet_count("doctype", Document.facet_doctype, func.count().desc(), lambda v: v) return result