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