Closed mzealey closed 4 years ago
I had not but I don't think it provides the full exists / not exists functionality eg spanning multiple cols via join criteria?On 29 Dec 2018 17:15, fREW Schmidt notifications@github.com wrote:Have you see https://metacpan.org/pod/DBIx::Class::Helper::ResultSet::CorrelateRelationship ?
—You are receiving this because you authored the thread.Reply to this email directly, view it on GitHub, or mute the thread.
Sure, you can do multi-column relationships in DBIC; here's an example (using ::Candy and ::DWIM to shorten the definition:)
belongs_to alarm_channel => '::AlarmChannel', {
'foreign.user' => 'self.user',
'foreign.site' => 'self.serial',
'foreign.alarm' => 'self.alarm',
'foreign.alarmstate' => 'self.alarmstate',
};
@frioux Sure you can do joins like that. But lets say I want to search for items which dont't have a particular tag
SELECT *
FROM items
WHERE NOT EXISTS (SELECT 1 FROM item_tags WHERE items.id = item_tags.item_id AND some other criteria LIMIT 1)
I could do this as a left join checking for null but a) that is often much more intensive on the DB side (certainly in MySQL it can't optimize so well) and b) returns all the joined rows for items which have multiple tags which would later need filtering. I could also do this as corrolated with count and a having but again the correct way (and one which database can optimize much more simply) is to do the (NOT) EXISTS filters. If you have a join in the query the (NOT) EXISTS also allows you to reference multiple tables as well which is very powerful.
Sorry I should have given a more complete example; the following should do what you just said:
$rs->search({
-not_exists => $rs->correlate('item_tags')
->search({ some other criteria }, { rows => 1 })->as_query
})
Honestly I'm ok with your PR on the face of it, I just think it reimplements some stuff that is already implemented; Just trying to make sure I'm not missing something.
@frioux OK I see what you mean now. I wasn't aware that could be done (both the corrolate and the -exists
) and I can't see it documented anywhere as such - perhaps you could add exists/not exists to a cookbook somewhere so it is more obvious when searching? Only advantage that my code brings is that you can do dynamic joins but I'm sure there are other ways to do that and generally you shouldn't be doing that within dbic.
Yeah honestly I was scouring the docs to link you to them and couldn't find anything. I fully agree that it should be documented and found.
I actually think dynamic joins are really useful! When I was trying to find examples of where I'd used -exists
I found dynamic joins in my own code because it explicitly had no relationships because it was an initial migration.
Here's an idea: update your docs (there are some parts that are no longer correct, like the alias thing) and add some explanations of -exists
and -not_exists
; even if we get a patch into the cookbook, more examples in relevant places tend to be useful.
Would you be up for me writing something like ResultSet/Exists.pod based around the correlate functionality so people searching can find it more easily?
Sure!
Per the POD this adds
$rs->exists( $subq, { join cond } )
and->not_exists(...)
support