La respuesta obvia aquí es tener una sola clase que represente el objeto, luego una referencia al objeto principal, si lo hay. La consulta a través del árbol sería comenzar en un nodo dado del árbol y devolver todos los objetos principales de ese nodo. Cada nodo tendrá solo un nodo padre directo.
¿Hay una mejor manera de hacer esto computacionalmente o desde una perspectiva de diseño de software?
EDITAR: Buscando sugerencias de mejora de la complejidad computacional o sugerencias de mantenimiento. La memoria no es un gran problema aquí.
@Thomas uno relacional. No estoy seguro de cuál es la opinión de nuestro equipo sobre los procesos almacenados, pero si hay una razón lo suficientemente convincente para usarlos, estoy seguro de que puedo defender el caso.
En una base de datos relacional, usaría una expresión de tabla común
WITH foo AS ( -- your start node SELECT * FROM MyData AS d WHERE d.id = 123 UNION ALL -- traversing up SELECT parent.* FROM MyData AS parent JOIN foo AS child ON parent.id = child.parentId ) -- selecting the data you want to return from the CTE SELECT * FROM foo;En términos de JS, aquí hay una descripción de lo que hace la consulta anterior:
// initial SELECT var foo = myData.filter(item => item.id === 123); // UNION ALL + SELECT with JOIN onto `foo` for (let i = 0; i < foo.length; ++i) { foo.push(...myData.filter(item => item.id === foo[i].parentId)); } console.log(foo);solo que una selección de DB es mucho más rápida y de mayor rendimiento que Array#filter() en el código JS, pero básicamente producen el mismo resultado; una lista de (0 o más) coincidencias