-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/search work by tag #99
Changes from all commits
c789865
55ba83a
5841f38
f8d0107
ed342b8
fc3f7fa
7dd2398
923b7c5
4a3b763
4d3dedc
793e6c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from typing import List | ||
from fastapi import HTTPException | ||
from sqlalchemy import desc, func | ||
from cruds.assets import delete_asset_by_id | ||
from cruds.url_infos import create_url_info, delete_url_info | ||
from db import models | ||
|
@@ -76,18 +77,16 @@ def set_work(db: Session, title: str, description: str, user_id: str, | |
|
||
return work | ||
|
||
def get_work_by_id(db: Session, work_id: str) -> Work: | ||
work_orm = db.query(models.Work).get(work_id) | ||
if work_orm == None: | ||
return None | ||
return Work.from_orm(work_orm) | ||
|
||
|
||
def get_works_by_limit(db: Session, limit: int, visibility: models.Visibility, oldest_id: str, auth: bool = False) -> List[Work]: | ||
works_orm = db.query(models.Work).order_by(models.Work.created_at).filter( | ||
models.Work.visibility != models.Visibility.draft) | ||
def get_works_by_limit(db: Session, limit: int, visibility: models.Visibility, oldest_id: str, tags: str, auth: bool = False) -> List[Work]: | ||
works_orm = db.query(models.Work).order_by(desc(models.Work.created_at)).filter(models.Work.visibility != models.Visibility.draft) | ||
if tags: | ||
tag_list = tags.split(',') | ||
works_orm = works_orm.filter(models.Tagging.tag_id.in_(tag_list)).filter(models.Tagging.work_id == models.Work.id) | ||
works_orm = works_orm.group_by(models.Work.id).having(func.count(models.Work.id) == len(tag_list)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これって何してるん? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tag_list = tags.split(',') ','で区切ったtag_idを配列にして, works_orm = works_orm.filter(models.Tagging.tag_id.in_(tag_list)).filter(models.Tagging.work_id == models.Work.id) Taggingテーブルからそのタグが付いたデータを抽出して,そのデータのwork_idと一致する作品情報をWorkテーブルから持ってきて, works_orm = works_orm.group_by(models.Work.id).having(func.count(models.Work.id) == len(tag_list)) 重複してる作品をGROUPで一纏めにして,重複したデータ数がタグの数と一致したもので更に絞り込んでます. SQLっぽく書くと, SELECT works.* FROM works, tagging
WHERE tagging.tag_id in ("tagid1", ..., "tagid2") AND tagging.work_id = works.id
GROUP BY works.id HAVING count(works.id) = 4; -- 4はタグの数 って感じです. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
なるほど、理解 |
||
if oldest_id: | ||
limit_work = db.query(models.Work).filter(models.Work.id == oldest_id).first() | ||
if limit_work is None: | ||
raise HTTPException(status_code=400, detail='this oldest_id is invalid') | ||
limit_created_at = limit_work.created_at | ||
works_orm = works_orm.filter(models.Work.created_at > limit_created_at) | ||
if not auth: | ||
|
@@ -249,4 +248,4 @@ def get_works_by_user_id(db: Session, user_id: str, at_me: bool = False, auth: b | |
works_orm = works_orm.filter(models.Work.visibility == 'public').all() | ||
|
||
works = list(map(Work.from_orm, works_orm)) | ||
return works | ||
return works |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,3 +40,6 @@ class Work(BaseModel): | |
|
||
class Config: | ||
orm_mode = True | ||
|
||
class SearchOption(BaseModel): | ||
tags: list[str] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
タグで絞り込んで作品数が減った後にソートした方が処理が早い気がする
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sqlalchemyはall()やfirst()などが付くまではSQLを構成するだけで実行はされないため全て記述した順番通りに実行されるわけではないと記憶しております.
また,そもそもPostgreSQLではソートを行ったあとで絞り込みを行うという記述は実行することが出来ないため,正常に動作していることからも問題ないと考えています.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
そっか
ほんまやわw