Arranging data by the parent and child relationship with Drizzle ORM

Currently, I am utilizing Drizzle ORM paired with TypeScript, and within my database schema, I have a table that references itself for categories, allowing them to have parent categories. My objective is to execute a query that retrieves the categories sorted by their parentId first, followed by the id, in order to maintain the hierarchical relationship between parent and child categories.

Below is the structure of the schema:

import { pgTable, uuid, timestamp, varchar, text } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

export type CategoryId = number & { __typeName: 'Category' };

export const categories = pgTable('categories', {
  id: uuid('id').$type<CategoryId>().defaultRandom().primaryKey(),
  createdAt: timestamp('createdAt').defaultNow().notNull(),
  title: varchar('title').notNull(),
  description: text('description').notNull(),
  parentId: uuid('parentId').references((): AnyPgColumn => categories.id),
});

export type Category = typeof categories.$inferSelect;

export const categoriesRelation = relations(categories, ({ many, one }) => ({
  subcategories: many(() => categories, { relationName: "subcategories" }),
  parent: one(() => categories, {
    fields: [categories.parentId],
    references: [categories.id],
    relationName: "subcategories"
  }),
}));

Sample dataset: Representation in the Database

CategoryId ParentId Title
--------------------------
1          null     Pets      
2          1        Pet bowls 
3          null     Cloth
4          3        Accessories
5          2        Pet bowls with some specific

The desired output:

CategoryId ParentId Title
--------------------------
1          null     Pets      
2          1        Pet bowls
5          2        Pet bowls with some specific
3          null     Cloth
4          3        Accessories

Answer №1

It is unlikely that you can achieve the desired result using the drizzle orm API.

Your requirement for specific ordering goes beyond the capabilities of the column order in drizzle API. This kind of customization should ideally be handled at a higher application layer rather than within the ORM itself, as it seems to be more related to UI representation. A simple algorithm implemented at the appropriate level could potentially solve this issue.

const getArangedList = (input: Array<Category>, parent: Category | undefined = undefined, depth = 0): Array<Category> => {
    if (depth >= 50) {
        throw new Error(`Cannot get getArangedList. Max recursion depth exceeded`)
    }

    const result: Array<Category> = [];

    if (parent) result.push(parent);

    const subCategoryesSorted = input.filter((c) => c.parentId === parent?.id).sort(sortByIdAsc);
    const subCategoriesResults = subCategoryesSorted.flatMap((subCategory) => getArangedList(input, subCategory, depth + 1));
    result.push(...subCategoriesResults);

    return result;
}

A complete example can be found here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering the art of line breaks

Imagine I have a random block of text displayed in a single line, like this: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Due to various reasons such as width settings or text-zoom, the text may display as two or more lines on the viewer&apos ...

Error in Javascript: unable to locate the imported module

When attempting to import the 'CryptographyClient' module from a specified directory, I encountered an issue. Initially successful in typescript, but after compiling the code into javascript, an error was thrown stating that it could not find the ...

What is the best approach to comply with the EsLint rule "react-hooks/exhaustive-deps" and properly implement componentDidMount using hooks in React with a warning level?

After reviewing the React documentation, it appears that componentDidMount is now implemented using hooks as shown below: useEffect(() => { // your code here }, []) For example, if you wish to make an API call within this hook: useEffect(() => { ...

The saving functionality of InnerBlocks in WordPress' Gutenberg editor is not working properly

My InnerBlock seems to be functioning correctly when nesting blocks on a page, saving, and viewing the page. However, upon attempting to edit the page again, I encounter a Block validation failed error: Content generated by `save` function: <div class= ...

Triggering an Ajax request by clicking on a link

In the scenario where you have a specific word on a webpage that you would like to trigger an onclick event and initiate an ajax request, what is the best approach to accomplish this? ...

What is the best approach for handling @RequestParam in a JSP file?

Hello there! I have a query regarding the usage of @RequestParam in @RestController. My question is about extracting @RequestParam from the client side. Below is an example of server code using @RestController: @ResponseBody @RequestMapping(method = Reque ...

Automatic Form Saving in Angular 4

Seeking to create a form data autosave feature in Angular 4. The functionality should operate as follows: User modifies data in the form -> save request sent to DB. A timer is initiated for 2 seconds. During the 2-second window after the previous s ...

Encountered an issue with importing a JavaScript library in TypeScript

I am trying to import a JavaScript library called Akarata. I have followed the suggestions from the internet, such as: import * as akarata from 'akarata/dist'; or import * as akarata from 'akarata'; However, I am still encountering ...

Adjusting the size of DIVs according to images retrieved dynamically from a database

I am currently in the process of building my online portfolio, and while I am new to JQuery and PHP, I am working through any challenges that come my way. However, I am facing a roadblock that has left me puzzled. My goal is to create a seamless iframe to ...

Having trouble extracting a list of matches using a Regular Expression?

const stringWithDate: string = "4/7/20 This is a date!"; const reg: RegExp = new RegExp("^(\d{1,2}\/\d{1,2}\/\d{1,2})").compile(); const exist: boolean = reg.test(stringWithDate) const matches: RegExpExecArray | null = reg.exec(str ...

Unable to access the get method of an undefined node.js object

I'm currently working on implementing a new structure and scalability approach for an express application. Challenge: I am looking for a way to automatically load routes without having to define each one in the app.js file. Proposed Solution: I ai ...

Unable to retrieve values from nested objects in component.html

Hey fellow tech enthusiasts, I'm currently dealing with a complex nested JSON object retrieved from an API. Here's a snippet of the object: profile : { title:"Mr", personalInfo:{ fullNames: "John Doe", id ...

Adjust the content size to 100% based on the quantity of items in a row

I've been having a hard time creating an image gallery that adjusts its size automatically (width: 100%) based on the number of items it contains. For example, take a look at this gallery: http://codepen.io/anon/pen/eNMOEz .item { width: 75px; h ...

The data retrieved from the Redis cache does not have pagination implemented

After incorporating Redis cache into my backend API, I encountered an issue where pagination no longer worked on both the backend and frontend. Here is a snippet of the middleware that executes before retrieving all data: const checkCache = (req, res, next ...

Retrieving input value in an Android WebView

I recently attempted to extract the value of an input type and store it as a string within my Android WebView. Unfortunately, I couldn't find a straightforward solution. The snippet of code in my HTML file is as follows: <input class="input100 ...

Tips for passing the name of a success function as a parameter in an AJAX request

My challenge is to create an AJAX call as a single function, where I pass the success function name as a parameter. Here's the function that I attempted: function MakeApiCall(dataText, apiName, functionName) { $.ajax({ url: apiUrl + apiName, ...

How to Fix Items Being Pushed Down by 'Particleground' Jquery Plugin Due to Z-Index and Positioning

I'm grappling with understanding z-index and positioning, despite reading various questions and articles on the topic. Currently, I'm attempting to incorporate a Jquery Plugin called 'Particleground': https://github.com/jnicol/particle ...

The error message [TypeError: attempting to access 'getDocumentsDirectory' property on a null object] was encountered

I have been attempting to generate a PDF within my application using react-native-pdf-lib. However, I keep encountering the following error: [TypeError: null is not an object (evaluating '_reactNativePdfLib.default.getDocumentsDirectory')] Here ...

Adding the state of an object to an existing array of objects using the useState

My goal is to create an array of objects structured like this [{},{},{}] The state variable is constructed as shown below: this.state:{...some states, parsed:[{}]} Each object is obtained from IPFS using an async function: IPFSREADER = ele ...

Exporting a SkinnedMesh with position using Three.js

I am attempting to export a model from a Three.js scene using the OBJExporter.js found at https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/OBJExporter.js Within the scene, I have both base meshes and SkinnedMeshes. To account for this ...