0

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

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 真的很陌生。

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

4

1 回答 1

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

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

于 2020-04-19T12:27:36.150 回答