【问题标题】:Sort by matched tags with SQLAlchemy使用 SQLAlchemy 按匹配的标签排序
【发布时间】:2020-04-19 10:17:44
【问题描述】:

我有以下表格。我想按标签搜索,并按匹配的标签数排序。

class DocumentTag(db.Model):
    __tablename__ = "document_tag"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    user_document_id = db.Column(db.Integer, db.ForeignKey("user_document.id"))
    order = db.Column(db.Integer, nullable=False)

    user_document = db.relationship("Document")

class UserDocument(db.Model):
    __tablename__ = "user_document"
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    document_id = db.Column(db.Integer, db.ForeignKey("document.id"), nullable=False)
    date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    last_accessed = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    document_tags = db.relationship(
        "DocumentTag",
        order_by="DocumentTag.order",
        collection_class=ordering_list("order"),
    )
    document = db.relationship("Document")
    document_tag = db.relationship("DocumentTag")

我尝试用这样的标签搜索文档。


tags = ['tag_1', 'tag_2'] # this is tags to search

documents_tags_count = (
    db.session.query(
        UserDocument, func.count(DocumentTag.id).label("num_corres_tags")
    )
    .join(UserDocument, DocumentTag.user_document) # in order to count combination of document_tags and tags
    .filter(
        UserDocument.document_tags.any(DocumentTag.name.in_(tags)),
        UserDocument.user_id == current_user.id,
    )
    .group_by(UserDocument)
    .order_by(desc("num_corres_tags"))
)

但是,标签num_corres_tags 显示的不是过滤的标签数量,而是属于文档的所有标签数量。我想做的是按匹配(过滤)标签的数量获得排序结果。

我在这里看到了一些关于 MySQL 的类似问题,但我找不到任何关于 SQLAlchemy 的解决方案,因为我对 SQL 真的很陌生。

有什么办法可以解决我的问题吗?

【问题讨论】:

    标签: python sql flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    由于您显式加入 DocumentTag 以进行计数,因此也使用该联接进行过滤,而不是单独使用 EXISTS 子查询表达式:

    documents_tags_count = (
        db.session.query(
            UserDocument, func.count(DocumentTag.id).label("num_corres_tags")
        )
        .join(UserDocument, DocumentTag.user_document) # in order to count combination of document_tags and tags
        .filter(
            DocumentTag.name.in_(tags),
            UserDocument.user_id == current_user.id,
        )
        .group_by(UserDocument)
        .order_by(desc("num_corres_tags"))
    )
    

    现在结果仅限于匹配标签,并且计数应该是您所期望的。

    【讨论】:

    • 非常感谢!我被这个问题困扰了很久,但我已经尝试过了,效果很好!
    猜你喜欢
    • 2013-01-14
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2011-08-04
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多