【问题标题】:Querying a Sequelize model to match multiple associations查询 Sequelize 模型以匹配多个关联
【发布时间】:2018-08-13 10:05:02
【问题描述】:

所以我有两个具有这种关系的 Sequelize 模型:

models.Note.belongsToMany(models.Topic, {
 through: 'noteTopicRelation'
});

models.Topic.belongsToMany(models.Note, {
 through: 'noteTopicRelation'
});

我可以像这样对 Note 模型进行成功的查询,获取属于 id 为 2 的 Topic 的所有 Notes:

models.Note.findAll({
 include: [{
   model: models.Topic,
   through: 'noteTopicRelation',
 }]
 where: {
  '$topics.id$': 2
 }
})

但是,如果我只想要一个与多个特定主题相关联的便笺(即与 id 为 1、4、6 的主题相关联的便笺)怎么办?

我已尝试在我的 where 上添加此运算符:

where: {
'$topics.id$': {$overlap: [1, 4, 6]}
}

但出现错误:

操作符不存在:uuid && text[]

我是否错误地使用了Op.overlap?有没有其他方法可以达到这个结果?谢谢!

编辑: 并且只是为了澄清(对不起,如果这在我的原始帖子中不清楚),我想获得与 all 严格相关的注释那些话题。执行'$topics.id$': [1, 4, 6] 会得到与这些主题中的任何相关联的注释。

【问题讨论】:

    标签: javascript postgresql sequelize.js model-associations


    【解决方案1】:

    我认为你想要$in 而不是$overlap;后者映射到 PostgreSQL && 运算符,该运算符用于范围类型,而不是列表。

    所以我建议尝试:

    where: {
      '$topics.id$': [1, 4, 6]
    }
    

    上面将获得具有任何主题 ID 的注释(在编辑问题之前发布,说只应返回所有提供的 topic.ids 的注释)。

    根据下面 cmets 中 Sequelize github 问题页面上的讨论链接;使用所有主题 ID 获取笔记的一种方法,您需要执行以下操作:

    var topicIds = [1, 4, 6];
    models.NoteTopicRelation
        .findAll({
            include: [
                {model: models.Topic, where: {id: topicIds}}
            ],
            group: ['note_id'],
            having: ['COUNT(*) >= ?', topicIds.length]
        })
        .then((noteTopicItems) => models.Note.find({
            where: {id: noteTopicItems.map((item) => item.note_id)}
        }))
        .then((notes) => {
            // do something with notes
        });
    

    请注意,此方法仅在链接表(即您的情况下为 noteTopicRelation)只有唯一的 note_idtopic_id 对时才可靠工作 - 即。这些字段上有某种unique 键。否则,一个主题可以多次分配给一个注释,这将抛出COUNT(*)。我相信 Sequelize 创建的默认“通过”表在两个字段上都有一个 unique 键;在某些合法的情况下,这可能不是我们所希望的,所以我认为值得一提。

    另请注意,我在上述查询中对您的 noteTopicRelation 模型的列/属性名称做了一些假设,因此您可能需要对其进行调整。

    另一件需要注意的事情 - 在示例案例中,从 NoteTopicRelation 到 Topic 的连接并不是真正必要的;如果您只想按topic.id 过滤,您可以使用where: {topic_id: topicIds}(这将避免加入Topic)更有效地实现相同的目的。我已经把连接留在那里,以防你真的想查询例如主题名称或在where 子句中包含来自Topic 模型/表的其他属性(例如enabled 属性或类似属性)。

    【讨论】:

    • 我觉得你可以简化一点,像这样:where: { '$topics.id$': [1, 4, 6] } Sequelize automaticaly add in
    • 当然谢谢!我忘了...我已经用你的简化编辑了答案。
    • 嘿@Timshel,感谢您的帖子!抱歉,如果我在原始帖子中不清楚,但我想获取与所有这些主题严格相关的注释。执行您建议的方法可以让我获得与其中任何一个相关的注释。我的错是不清楚(仍然不知道这是否完全清楚)。更新了我的帖子!
    • 好吧,这有点困难——从 SQL 的角度来看,实现这一点的最简单方法是多次内部连接到链接表(即 noteTopicRelation)——每个主题 ID 一次。我认为这不能使用基本的 Sequelize 查询来完成。你最好写一个直接的 SQL 查询或存储过程来完成这项工作
    • 阅读this fairly detailed discussion on Sequelize's github issues page 了解如何实现这一点。此解决方案使用单个连接以及 GROUP BYHAVING COUNT(*) = [number of topics] 语句来仅获取具有 ALL 主题的注释(使用您的数据库术语)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多