查询Sequelize模型以匹配多个关联

时间:2018-08-13 10:05:02

标签: javascript postgresql sequelize.js model-associations

所以我有两个具有这种关系的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: {
'$topics.id$': {$overlap: [1, 4, 6]}
}

但是出现错误:

  

运算符不存在:uuid && text []

我使用Op.overlap的方式有误吗?还有另一种方法可以达到这个结果吗?谢谢!

编辑:并且仅作澄清(对不起,如果我的原始帖子中不清楚),我想获取与以下内容的 all 严格相关的注释这些主题。执行'$topics.id$': [1, 4, 6]将使我得到与这些主题的 any 相关的笔记。

1 个答案:

答案 0 :(得分:1)

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

所以我建议尝试:

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

以上内容将获得带有任何主题ID的注释(在问题编辑之前发布,以说仅应返回包含所有提供的topic.id的注释)。

根据以下评论中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的连接并不是必需的。如果您只想按where: {topic_id: topicIds}进行过滤,则可以使用Topic更有效地完成同一件事(这将避免加入topic.id)。如果您确实想查询例如,我将联接留在那里。主题名称或在Topic子句中包含where模型/表中的其他属性(例如enabled属性或类似属性)。