Here's the answers I came up with to my initial questions, though I doubt it is the highest performance method:
- How do I get rid of duplicate club_ids for children and parents?
Insert DISTINCT into the agg_array function
- It's a really slow query. If it is indexed, will the view be updated every time a write happens on child or parent?
The query is slow. Creating the view is very quick. The view, as I currently understand, really provides a convenient way for doing searches. The view is not a "real" table. I think this is why making sure your are indexing all of the search terms of the view. You are not indexing the view itself.
Also, I ended up moving the email address into its own query so that became a search term as well.
Here was my final query that I based the view on:
SELECT
families.id AS family_id,
'Child' AS searchable_type,
concat(children.first_name, ' ',children.last_name) AS term,
array_agg(DISTINCT memberships.club_id) AS clubs
FROM children
INNER JOIN families ON children.family_id = families.id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term
UNION
SELECT
families.id AS family_id,
'Parent' AS searchable_type,
concat(parents.first_name, ' ',parents.last_name) AS term,
array_agg(DISTINCT memberships.club_id) AS clubs
FROM parents
INNER JOIN families ON parents.family_id = families.id
INNER JOIN children ON families.id = children.family_id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term
UNION
SELECT
families.id AS family_id,
'Parent' AS searchable_type,
email AS term,
array_agg(DISTINCT memberships.club_id) AS clubs
FROM parents
INNER JOIN families ON parents.family_id = families.id
INNER JOIN children ON families.id = children.family_id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term