2017-01-26 6 views
2

ContactThreadの2つのモデルがあり、多対多の関係が結合表ThreadContactsで表されています。Sequelize:異なる条件で同じ結合表を照会します

私はに問い合わせを書く必要があります。連絡先の正確なリストとの関連付けを持っているスレッドを見つける。たとえば、contact_idの [1,2,3,4]のリストがあり、正確な4つの連絡先に関連付けられているThreadが必要です。

私はfindAllのクエリにContact含めて試してみました。もちろん

Thread.findOne({ 
    include: [{ 
     model: Contact, 
     where: { id: $in: [1, 2, 3, 4] }, 
    }], 
}) 

それは4つのIDのいずれかとThreadContactを持っているスレッドを返しますので、これは動作しません。

私はこのような何か必要があります:それは同じモデルの重複を含めているので、これも動作しません。しかし

Thread.findAll({ 
    include: contactIds.map(id => ({ 
     model: Contact, 
     where: { id }, 
    }), 
}) 

を。

ここには何がありますか?私はこのための解決策を見つけるのが難しい時があります。

答えて

1

より複雑な結合クエリを後発させて書くと、通常はraw query interfaceが使用されてしまいます。それは少し複雑に見えますが、うまくいけば、それは理にかなって:

  • スレッドを選択し、Thread.id
  • によって
  • グループにThreadContactテーブルと結合接触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]}, 
}); 

また、モデルが定義されている方法から列名が正しくない可能性があることにも注意してください。

+0

代わりに、これは私が 'join 'を行う必要があるときに使うものですが、これをやっている"続ける "方法の例を見たいと思っています。 –

+0

ええ、Sequelizeで見るのはいいですが、これは私のアプリケーションではうまくいきます。ありがとう:) –

+1

ARRAY [:contactIds]と array_agg(thread_contacts.contact_id)の配列識別子(*)の配列*の正確な*リストが含まれている必要があるため、 <@ ARRAY [:contactIds]; ' –

関連する問題