简体   繁体   English

使用 SQLAlchemy 按匹配的标签排序

[英]Sort by matched tags with SQLAlchemy

I have following tables.我有下表。 I want to search by tags, and sort by matched number of tags.我想按标签搜索,并按匹配的标签数排序。

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")

I tried to search documents with tags like this.我试图用这样的标签搜索文档。


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"))
)

However, the label num_corres_tags showed not filtered number of tags but all number of tags which belongs to the documents.但是,label num_corres_tags显示的不是过滤的标签数量,而是属于文档的所有标签数量。 What I wanted to do was get ordered result by number of matched (filtered) tags.我想要做的是通过匹配(过滤)标签的数量获得排序结果。

I saw some similar questions for MySQL here, but I couldn't find any solution for SQLAlchemy because I'm really new to the SQL.我在这里看到了 MySQL 的一些类似问题,但我找不到 SQLAlchemy 的任何解决方案,因为我对 SQL 真的很陌生。

Is there any ideas to solve my problem?有什么想法可以解决我的问题吗?

Since you explicitly join DocumentTag in order to count, use that join to do the filtering as well instead of using an EXISTS subquery expression separately:由于您显式连接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"))
)

Now the results are limited to matching tags only and the count should be what you expected.现在结果仅限于匹配标签,并且计数应该是您所期望的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM