我有两个模型Contact
和Thread
,在关联表ThreadContacts
中表示多对多关系。
我需要写一个查询查找与联系人的确切列表有关联的主题。例如,我可能有一个contact_id
的列表
[1,2,3,4],我需要找到与这4个联系人相关联的Thread
。
我尝试在findAll查询中包含Contact
:
Thread.findOne({
include: [{
model: Contact,
where: { id: $in: [1, 2, 3, 4] },
}],
})
当然这不起作用,因为它会返回一个ThreadContact与4个ID中的任何一个的线程。
我需要这样的东西:
Thread.findAll({
include: contactIds.map(id => ({
model: Contact,
where: { id },
}),
})
然而,这也不起作用,因为它包含相同型号的副本。
我有什么选择?我很难找到解决方案。
答案 0 :(得分:1)
在sequelize中编写更复杂的连接查询时,我通常最终使用raw query interface。它看起来有点复杂,但希望它有道理:
Thread.id
array_agg
汇总群组。所以我们现在为每个线程都有一个所有相关联系人的数组。@>
表示)您输入的过滤器。见postgres array functions。结果将是与至少4个联系人相关联的所有主题。
sequelize.query(`
SELECT Thread.*
FROM Thread
INNER JOIN ThreadContact
ON Thread.id = ThreadContact.threadId
GROUP BY Thread.id
HAVING array_agg(ThreadContact.contactId) @> ARRAY[:contactIds];
`, {
model: Thread,
mapToModel: true,
type: sequelize.QueryTypes.SELECT,
replacements: {contactIds: [1, 2, 3, 4]},
});
另请注意,根据模型的定义,列名可能不正确,我只是对它们的外观做了一些假设。