-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RelationshipCache - Add a high-level index to facilitate relationship queries (more fields) #17781
Conversation
(Standard links)
|
We're almost there. I would like to request 2 changes to this before merging:
|
b28a1e6
to
af5eee8
Compare
@colemanw Alrighty, updates:
|
@civicrm-builder retest this please |
@totten jenkins is falling over trying to apply the patch from this PR because it attempts to simultaneously add and delete the same files. It's because you renamed them. |
This is the more maximal variant of the schema which includes mirrors for most fields.
…st. Use syncInto().
af5eee8
to
9cbdbf0
Compare
@civicrm-builder retest this please |
I've done |
Overview
In CiviCRM, "relationships" are user-configurable relations between two contacts. The data-structure which represents these configurable relationships is complicated to query. This PR adds a supplemental data-structure (the "relationship cache") which makes it more, eh, relatable.
(NOTE: This is a rebased and extended version of #17724 which mirrors additional relationship data to further simplify querying. The original description was a bit curt; I've rewritten to incorporate more of the original explanation from #17724.)
Before
Each end of the relationship may be given a name (e.g.
Spouse of
,Child of
,Parent of
). In thecivicrm_relationship_type
, this corresponds to a few columns (partial listing):civicrm_relationship_type
.id
civicrm_relationship_type
.name_a_b
civicrm_relationship_type
.name_b_a
When a specific relationship is created between two contacts, Civi creates correlated values in the
civicrm_relationship
table (partial listing):civicrm_relationship
.relationship_type_id
civicrm_relationship
.contact_id_a
civicrm_relationship
.contact_id_b
The difficulty arises when building queries on this data - as a consumer of the data, I know the name of a relation that interests me (eg
Parent of
). I need to know which column (contact_id_a
orcontact_id_b
) corresponds to each side of the relationship, and then orient the query structure to match. Depending on the metadata stored incivicrm_relationship_type
, I may need swap amongcontact_id_a
andcontact_id_b
in different places - or I may need to query both ways andUNION
the result. This grows increasingly complicated if you wish query on multiple relationship-types.After
You may query
civicrm_relationship_cache
, which has these columns:id
,relationship_id
,orientation
near_contact_id
,near_relation
,far_contact_id
,far_relation
relationship_type_id
,start_date
,end_date
,is_active
The most important columns are the perspective columns. As query author, you should match your initial contact against
near_contact_id
; the counterparty will always be infar_contact_id
. Thenear_relation
will describe the relationship from the perspective of the near contact (andfar_relation
describes the perspective of the far contact).For example, if Alice (
#100
) is the parent of Bob (#200
), then thecivicrm_relationship_cache
would have these two records:near_contact_id
near_relation
far_contact_id
far_relation
#100
)Parent of
#200
)Child of
#200
)Child of
#100
)Parent of
Examples
Suppose we have a contact Alice (
#100
) and want to see which contacts are her children. We can query:Suppose we want to lookup the immediate family (parents, children, siblings, spouses) for everyone named "Bob" - and display their names:
Which produces output like this:
The nice thing to note here is that we did not have do any accounting for the orientation of the relationship -- there are no unions and there is no switching between
contact_id_a
andcontact_id_b
. We start from our initial contact ID (bob
) and simply join the relationship'snear_contact_id
. The relationship is effortlessly examined from Bob's perspective.Technical Details
For every record in
civicrm_relationship
, there are two records incivicrm_relationship_cache
. (One record from the perspective ofcontact_id_a
; and the other record from the perspective ofcontact_id_b
.) This mapping is enforced at runtime via trigger, and it is initialized during upgrade.This PR only aims to provide the data-structure. There is a follow-up need to enhance APIv4's
Relationship
support to take advantage of this mechanism.