{"id":6386,"date":"2019-02-17T19:35:55","date_gmt":"2019-02-18T03:35:55","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=6386"},"modified":"2025-06-13T17:22:10","modified_gmt":"2025-06-14T00:22:10","slug":"n1ql-query-with-self-referencing-hierarchy","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/","title":{"rendered":"N1QL query with Self Referencing Hierarchy"},"content":{"rendered":"<p>A data construct that often appears in business application is the hierarchical data structure. Hierarchy captures the parent-child relationship often between the same object. For instance a company structure captures the reporting line between employees. Business organization captures the relationship between parent companies and subsidiaries. Territory hierarchies in Sales. Book of accounts in financial applications.<\/p>\n<p>Due the self referencing nature of hierarchy, querying the structure efficiently along with its associated data can be a challenge for RDBMS, particularly from a performance perspective. In this article, I will discuss how traditional RDBMS handles hierarchical queries. The challenges that it has to deal with, and how this issue can be similarly addressed with Couchbase N1QL and Couchbase GSI.<\/p>\n<h2>Hierarchy Structure in Applications<\/h2>\n<p>The main reason for gathering information in a hierarchical structure is to improve the understanding of the information. Company reporting structure is designed, not only to help with how the organization is managed, but also provide a structure to measure and optimize the effectiveness of each group. In a large organization, sales performance is often assessed, not only at the individual level, but at sales team. In short, businesses organize information in a hierarchical structure so that they can get a better understanding of the business performance. In order to achieve that goal, business needs an efficient means to query the hierarchical data.<\/p>\n<h3>Representation of company hierarchy<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6402\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM.png\" alt=\"\" width=\"841\" height=\"428\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM.png 1676w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-300x153.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-1024x521.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-768x390.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-1536x781.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-20x10.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-17-at-7.33.47-PM-1320x671.png 1320w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><\/p>\n<p>While database data model is capable of efficiently capturing the hierarchical structure, the difficulty arises when you need to query the hierarchical data, and the related information.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Consider this requirement:\u00a0<\/strong><\/span><strong>Get a total sales order value for all sales reps who report up to ThomasH-Sales VP<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6397\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM.png\" alt=\"\" width=\"879\" height=\"356\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM.png 2098w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-300x122.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-1024x415.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-768x311.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-1536x622.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-2048x830.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-20x8.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-16-at-6.16.28-PM-1320x535.png 1320w\" sizes=\"auto, (max-width: 879px) 100vw, 879px\" \/><\/p>\n<p>While the data model is relatively simple. The hierarchical nature of the sales organization suggests an inherent dynamic structure in the reporting hierarchy. AjayW, who heads the Region1 territory, also manages the sales team members directly. Whereas, in Region2, Liz L manages two Managers, who then manages the sales team. This is typical in most application data hierarchies.<\/p>\n<h4>RDMBS approach<\/h4>\n<p>In order to query hierarchical data, more established RDBMS such as Oracle and SQLSever provide the CONNECT BY \/ START WITH construct to allow for a single query to recursively traverse the hierarchy employee structure.<\/p>\n<pre class=\"lang:tsql decode:true\" title=\"RDBMS - Sales orders generated by members who report up to ThomasH-Sales VP\">Query: Sales orders generated by members who report up to ThomasH-Sales VP&lt;\/strong&gt;&lt;\/span&gt;\r\n\r\nSELECT e.EmpID, e.Name, e.ManagerID, sum(o.orderVal)\r\n   FROM employee e\r\n   INNER JOIN sales_order o ON o.EmpID = o.EmpId\r\n   START WITH EmpID = 101\r\n   CONNECT BY PRIOR EmpID = ManagerID\r\n   GROUP BY  e.EmpID, e.Name, e.ManagerID;\r\n\r\n<\/pre>\n<p>While the above query may look simple, the query performance is difficult to improve with indexes due to the recursive nature of the CONNECT BY implementation. For this reason, this technique is not popular in application development for systems with large volume of data. Instead, enterprise applications rely on a pre-flattened object structure for a more predictable query performance. The flattened hierarchy technique is described in the Couchbase N1QL section below.<\/p>\n<h4>Couchbase N1QL<\/h4>\n<p>In order to get the best query performance, N1QL applications should use the flattened hierarchy structure. The approach\u00a0 provides more predictable performance as well as better at leveraging Couchbase GSI. The diagram below shows an example of the flattening transformation of a self-referencing hierarchical structure, such as the employee object. I also include a python code snippet below that you can use to flatten the hierarchical structure.\u00a0 The <strong><em>flatten_hierarchy<\/em><\/strong> function takes a self referencing hierarchical JSON object and generates two new objects in the same keyspace but with different type values<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6420\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\" alt=\"\" width=\"948\" height=\"416\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png 1774w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-300x132.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-1024x449.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-768x337.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-1536x674.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-20x9.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM-1320x579.png 1320w\" sizes=\"auto, (max-width: 948px) 100vw, 948px\" \/><\/p>\n<ul>\n<li>The <em>object_hier<\/em> structure works with aggregated BI queries, where query results can be rolled up for each level.<\/li>\n<li>The <em>object_hier_level<\/em> structure provides the same result as the CONNECT BY\/START WITH clause, which returns all of the child objects for any given node. This is the object that we will use in our N1QL query to provide the query solution.<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \" title=\"Query: Sales orders generated by members who report up to ThomasH-Sales VP SELECT e.EmpID, e.Name, e.ManagerID, sum(o.orderVal) FROM employee e INNER JOIN sales_order o ON o.EmpID = o.EmpId START WITH EmpID = 101 CONNECT BY PRIOR EmpID = ManagerID GROUP BY e.EmpID, e.Name, e.ManagerID;\">N1QL Query: Sales orders generated by members who report up to ThomasH-Sales VP\r\n\r\n\r\nSELECT e.id,sum(a.value)\r\nFROM crm a\r\nINNER JOIN (\r\n      SELECT uhl.id FROM crm uhl WHERE uhl.type ='_employee_hier_level'\r\n     AND uhl.parent='101') e USE HASH(probe) ON a.owner = e.id\r\nWHERE a.type='sales_order'\r\nGROUP BY e.id<\/pre>\n<p>Recommended GS Index:<\/p>\n<pre class=\"lang:default decode:true\">CREATE INDEX `crm_employee_hier_level` ON `crm`(`parent`) WHERE (`type` = \"_employee_hier_level\")<\/pre>\n<p>Notes:<\/p>\n<ol>\n<li>The main query retrieves all sales order in the <code>crm<\/code>\u00a0bucket with type value = &#8216;salesorder&#8217;<\/li>\n<li>The query performs a HASH JOIN with another query (N1QL 6.5 feature) that retrieves all the employee ids who report to user101, i.e ThomasH-SalesVP<\/li>\n<li>Additional covering indexes can also improve query performance<\/li>\n<li>The query uses N1QL 6.5 ANSI JOIN Support for Expression and Subquery Term<\/li>\n<\/ol>\n<pre class=\"font:consolas font-size:10 lang:python decode:true \" title=\"Python code snippet to flatten a hierarchy\"># Python code to flatten a JSON document in Couchbase bucket\r\nfrom couchbase.cluster import Cluster\r\nfrom couchbase.cluster import PasswordAuthenticator\r\nfrom couchbase.exceptions import NotFoundError\r\nfrom couchbase.bucket import Bucket\r\nfrom couchbase.n1ql import N1QLQuery\r\n\r\ndef flatten_hierarchy(cb,bucketname,src_doc_type,num_hier_level,node_id_col, parent_id_col):\r\n# Example: flatten_hierarchy(cb,args.bucket,'user',4,'id','managerid')\r\n# cb - couchbase bucket handle\r\n# bucketname - name of the bucket for the source and target documents \r\n# src_doc_type - the type value of the source document\r\n# num_hier_level - specifies the number of levels that are needed. Should be the max depth of the hierarchy\r\n# node_id - the field name in the document for the key node id\r\n# parent_node_id - the parent field \r\n#\r\n    gen_doc_type = '_'+src_doc_type+'_hier'\r\n    if (num_hier_level &gt; 1):\r\n        qstr_ins = 'INSERT into '+bucketname+' (KEY UUID(), VALUE ndoc) '\r\n        qstr_sel = 'SELECT { \"type\":\"'+gen_doc_type+'\"'     \r\n        for i in range(1,num_hier_level+1):\r\n            qstr_sel += ',\"id'+str(i)+'\":l'+str(i)+'.'+node_id_col\r\n        qstr_sel += '} ndoc'     \r\n        qstr_sel_one =  ' SELECT '+node_id_col+','+parent_id_col+' FROM '+bucketname+' WHERE type=\"'+src_doc_type+'\"'\r\n        for i in range(1,num_hier_level+1):\r\n            if (i==1):\r\n                qstr_sel += ' FROM ('+qstr_sel_one+') l'+str(i)\r\n            else:\r\n                qstr_sel += ' LEFT OUTER JOIN ('+qstr_sel_one\r\n                qstr_sel += ') l'+str(i)+' ON l'+str(i-1)+'.'+parent_id_col+' = l'+str(i)+'.'+node_id_col\r\n        try:\r\n            #q = N1QLQuery(qstring)\r\n            rows = cb.n1ql_query(qstr_ins+qstr_sel).execute()\r\n        except Exception as e:\r\n                print(\"query error\",e)\r\n        # generate connect by\r\n\r\n    if (num_hier_level &gt; 1):\r\n        qstr_ins = 'INSERT into '+bucketname+' (KEY UUID(), VALUE ndoc) '\r\n        qstr_sel = 'SELECT { \"id\":ll.child,\"parent\":ll.parent,\"level\":ll.level ,\"type\":\"'+gen_doc_type+'_level\" } ndoc FROM ('\r\n        for i in range(1,num_hier_level):\r\n            if (i&gt;1):\r\n                qstr_sel += 'UNION ALL '\r\n            qstr_sel += 'SELECT id'+str(i+1)+' parent, id1 child,'+str(i)+' level FROM '+bucketname+' WHERE type=\"'+gen_doc_type+'\" and id'+str(i+1)+' IS NOT NULL '\r\n        qstr_sel += ') ll'\r\n        try:\r\n            rows = cb.n1ql_query(qstr_ins+qstr_sel).execute()\r\n        except Exception as e:\r\n            print(\"query error\",e)\r\n    return<\/pre>\n<h4><b>Resources<\/b><\/h4>\n<ul>\n<li><i>Download<\/i>:\u00a0<a href=\"https:\/\/couchbase.com\/downloads?family=server&amp;product=couchbase-server-developer\">Download Couchbase Server 6.5<\/a><i><\/i><\/li>\n<li><i>Documentation<\/i>:\u00a0<a href=\"https:\/\/docs.couchbase.com\/server\/6.5\/introduction\/whats-new.html\">Couchbase Server 6.5 What\u2019s New<\/a><i><\/i><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/tag\/6-5\/\"><b>All 6.5 Blogs<\/b><\/a><\/li>\n<\/ul>\n<p>We would love to hear from you on how you liked the 6.5 features and how it\u2019ll benefit your business going forward. Please share your feedback via the comments or in the\u00a0<a href=\"https:\/\/www.couchbase.com\/forums\/\">forum<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A data construct that often appears in business application is the hierarchical data structure. Hierarchy captures the parent-child relationship often between the same object. For instance a company structure captures the reporting line between employees. Business organization captures the relationship [&hellip;]<\/p>\n","protected":false},"author":26326,"featured_media":6420,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1815,1819,1812],"tags":[2378],"ppma_author":[8919],"class_list":["post-6386","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-best-practices-and-tutorials","category-data-modeling","category-n1ql-query","tag-6-5"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>N1QL query with Self Referencing Hierarchy - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"N1QL query with Self Referencing Hierarchy\" \/>\n<meta property=\"og:description\" content=\"A data construct that often appears in business application is the hierarchical data structure. Hierarchy captures the parent-child relationship often between the same object. For instance a company structure captures the reporting line between employees. Business organization captures the relationship [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-02-18T03:35:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T00:22:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1774\" \/>\n\t<meta property=\"og:image:height\" content=\"778\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Binh Le\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Binh Le\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\"},\"author\":{\"name\":\"Binh Le\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63\"},\"headline\":\"N1QL query with Self Referencing Hierarchy\",\"datePublished\":\"2019-02-18T03:35:55+00:00\",\"dateModified\":\"2025-06-14T00:22:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\"},\"wordCount\":717,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\",\"keywords\":[\"6.5\"],\"articleSection\":[\"Application Design\",\"Best Practices and Tutorials\",\"Data Modeling\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\",\"name\":\"N1QL query with Self Referencing Hierarchy - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\",\"datePublished\":\"2019-02-18T03:35:55+00:00\",\"dateModified\":\"2025-06-14T00:22:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png\",\"width\":1774,\"height\":778},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"N1QL query with Self Referencing Hierarchy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63\",\"name\":\"Binh Le\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/5b68c37e30928a9d7b2c8470b1a303b7\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g\",\"caption\":\"Binh Le\"},\"description\":\"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Cloud Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/binh-le-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"N1QL query with Self Referencing Hierarchy - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/","og_locale":"en_US","og_type":"article","og_title":"N1QL query with Self Referencing Hierarchy","og_description":"A data construct that often appears in business application is the hierarchical data structure. Hierarchy captures the parent-child relationship often between the same object. For instance a company structure captures the reporting line between employees. Business organization captures the relationship [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/","og_site_name":"The Couchbase Blog","article_published_time":"2019-02-18T03:35:55+00:00","article_modified_time":"2025-06-14T00:22:10+00:00","og_image":[{"width":1774,"height":778,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png","type":"image\/png"}],"author":"Binh Le","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Binh Le","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/"},"author":{"name":"Binh Le","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63"},"headline":"N1QL query with Self Referencing Hierarchy","datePublished":"2019-02-18T03:35:55+00:00","dateModified":"2025-06-14T00:22:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/"},"wordCount":717,"commentCount":5,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png","keywords":["6.5"],"articleSection":["Application Design","Best Practices and Tutorials","Data Modeling","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/","url":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/","name":"N1QL query with Self Referencing Hierarchy - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png","datePublished":"2019-02-18T03:35:55+00:00","dateModified":"2025-06-14T00:22:10+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/02\/Screen-Shot-2019-02-20-at-8.59.12-AM.png","width":1774,"height":778},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-query-with-self-referencing-hierarchy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"N1QL query with Self Referencing Hierarchy"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/f89064928e262c71eb43bee996c48c63","name":"Binh Le","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/5b68c37e30928a9d7b2c8470b1a303b7","url":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","caption":"Binh Le"},"description":"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Cloud Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK.","url":"https:\/\/www.couchbase.com\/blog\/author\/binh-le-2\/"}]}},"authors":[{"term_id":8919,"user_id":26326,"is_guest":0,"slug":"binh-le-2","display_name":"Binh Le","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/a939f48df6447844a8780bec264bb3be21d589336f3915fabc557075a68fa374?s=96&d=mm&r=g","author_category":"","last_name":"Le","first_name":"Binh","job_title":"","user_url":"","description":"Binh Le is a Principal Product Manager for Couchbase Query service. Prior to Couchbase, he worked at Oracle and led the product management team for Sales Clould Analytics and CRM OnDemand. Binh holds a Bachelor's Degree in Computer Science from the University of Brighton, UK."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/6386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/26326"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=6386"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/6386\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/6420"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=6386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=6386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=6386"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=6386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}