0

If I am having any random accountId then How to find its ultimate parent account - looking for best-optimized solution (for multiple level hierarchy)

  • except 10 levels of formula field solution

1 Answers1

0

It depends. Optimized for what, read operations (instant simple answer when querying) or write (easy save but more work when reading).

If you want easy read - you need to put some effort when saving the data. And remember you can't get away with a simple custom lookup called "Ultimate Parent" - because for standalone account SF will not let you form a cycle, create record that looks up itself. You might need 2 text fields (Id and Name) or some convention that yes, you'll make a lookup to Account - but if it's blank - the reading process needs to check the ParentId field too to determine what exactly is going on. (you could make a formula field to simplify reading but still - don't think you're getting away with simple lookup)

How much data you have, how deep hierarchies? The basic answer is to keep track of ultimate parent on every insert, update, delete and undelete. Write a trigger, SOQL query can go "up" 5 "dots" max

SELECT ParentId, 
    Parent.ParentId, 
    Parent.Parent.ParentId,
    Parent.Parent.Parent.ParentId,
    Parent.Parent.Parent.Parent.ParentId,
    Parent.Parent.Parent.Parent.Parent.ParentId
FROM Account
WHERE Id IN :trigger.new

It gets messier if you need multiple queries (but still, this form would be most effective). And also you might hit performance issues when something reparents close to top of the tree and you're suddenly looking at having to cascade update hundreds of accounts. Remember you have a limit of 10K rows inserted/updated/deleted in single operation. You might have to propagate the changes down as a batch/future/queueable async process.

Another option would be to have a flat helper object aside from account table, with unique id set to account id. Have a background process periodically refreshing that table, even every hour. Using a batch job or reporting snapshot. Still not great if you have milions of accounts, waste of storage... but maybe you could use Big Objects.

Have you ever used platform cache? If the ultimate parent has to be fetched via apex (instead of being a real field on Account) - you could try to make some kind of "linked list" implementation where you store Id -> ParentId in cache and can travel it without wasting any queries. Cache's max is 48h (so might still need a nightly job to rebuild it) and you'd still have to update it on every insert/update/delete/undelete...

So yeah, "it depends". Write more about your requirement.

eyescream
  • 18,088
  • 2
  • 34
  • 46
  • Lets say I have 1 lac data of account already exist in the system, now as input I have one accountId given, then how should I find its ultimate parent Account (topmost) My thought on this if we use recursion to find ultimate parent that would hit governor limit as if we use query inside a recursive function – Feroz Patel Nov 29 '21 at 14:53
  • second thought if we use batch apex will that support for this as batch apex reinitialize governor limit, like we can query all accounts where parentId != null ,if this works then how to populate ultimateParent (customfiled on all account records), if not via batch apex , please suggest on this hope my question is clear – Feroz Patel Nov 29 '21 at 14:54
  • Lakh? 100K? Depend how big the hierarchy realistically is. With this query going 5 relationships up and 100 SOQL limit - will you really have data with 500 levels of parent-child, how business hopes to maintain it etc. I'd use recursion till I exhaust the limit of SOQLs and then probably call a "Queueable" to continue next chunk of this "going up" work until done. Nightly batch job should be fine too - but if you're genuinely worried about > 500 "jumps" then remember you can call just 1 Queueable out of a batch so it'd have to be fairly smart code or batch size set to 1? – eyescream Nov 29 '21 at 15:26