{"id":792,"date":"2012-01-27T19:13:00","date_gmt":"2012-01-27T19:13:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/storing-hierarchical-data-in-mongodb.html"},"modified":"2012-10-21T22:39:28","modified_gmt":"2012-10-21T22:39:28","slug":"storing-hierarchical-data-in-mongodb","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html","title":{"rendered":"Storing hierarchical data in MongoDB"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">Continuing NoSQL journey with <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>, I would like to touch one specific use case which comes up very often: storing hierarchical document relations. <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> is awesome document data store but what if documents have parent-child relationships? Can we effectively store and query such document hierarchies? The answer, for sure, is yes, we can. <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> has several recommendations how to store <a href=\"http:\/\/www.mongodb.org\/display\/DOCS\/Trees+in+MongoDB\">Trees in MongoDB<\/a>. The one solution described there as well and quite widely used is using materialized path.<\/p>\n<p>Let me explain how it works by providing very simple examples. As in previous posts, we will build <a href=\"http:\/\/www.springsource.org\/\">Spring<\/a> application using recently released version 1.0 of <a href=\"http:\/\/www.springsource.org\/spring-data\/mongodb\">Spring Data MongoDB<\/a> project. Our POM file contains very basic dependencies, nothing more.<\/p>\n<pre class=\"brush: xml;\">\r\n    4.0.0\r\n\r\n    mongodb\r\n    com.example.spring\r\n    0.0.1-SNAPSHOT\r\n    jar\r\n\r\n    \r\n        UTF-8\r\n        3.0.7.RELEASE\r\n    \r\n\r\n    \r\n        \r\n            org.springframework.data\r\n            spring-data-mongodb\r\n            1.0.0.RELEASE\r\n            \r\n                \r\n                    org.springframework\r\n                    spring-beans\r\n                \r\n                \r\n                    org.springframework\r\n                    spring-expression\r\n                \r\n            \r\n        \r\n\r\n        \r\n            cglib\r\n            cglib-nodep\r\n            2.2\r\n        \r\n\r\n        \r\n            log4j\r\n            log4j\r\n            1.2.16\r\n        \r\n\r\n        \r\n            org.mongodb\r\n            mongo-java-driver\r\n            2.7.2\r\n        \r\n\r\n        \r\n            org.springframework\r\n            spring-core\r\n            ${spring.version}\r\n        \r\n\r\n        \r\n            org.springframework\r\n            spring-context\r\n            ${spring.version}\r\n        \r\n\r\n        \r\n            org.springframework\r\n            spring-context-support\r\n            ${spring.version}\r\n        \r\n    \r\n\r\n    \r\n        \r\n            \r\n                org.apache.maven.plugins\r\n                maven-compiler-plugin\r\n                2.3.2\r\n                \r\n                    1.6\r\n                    1.6\r\n                \r\n            \r\n        \r\n    \r\n\r\n<\/pre>\n<p>To properly configure <a href=\"http:\/\/www.springsource.org\/\">Spring<\/a> context, I will use configuration approach utilizing Java classes. I am more and more advocating to use this style as it provides strong typed configuration and most of the mistakes could be caught on compilation time, no need to inspect your XML files anymore. Here how it looks like:<\/p>\n<pre class=\"brush: java;\">package com.example.mongodb.hierarchical;\r\n\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.data.mongodb.core.MongoFactoryBean;\r\nimport org.springframework.data.mongodb.core.MongoTemplate;\r\nimport org.springframework.data.mongodb.core.SimpleMongoDbFactory;\r\n\r\n@Configuration\r\npublic class AppConfig {\r\n    @Bean\r\n    public MongoFactoryBean mongo() {\r\n        final MongoFactoryBean factory = new MongoFactoryBean();\r\n        factory.setHost( \"localhost\" );\r\n        return factory;\r\n    }\r\n\r\n    @Bean\r\n    public SimpleMongoDbFactory mongoDbFactory() throws Exception{\r\n        return new SimpleMongoDbFactory( mongo().getObject(), \"hierarchical\" );\r\n    }\r\n\r\n    @Bean\r\n    public MongoTemplate mongoTemplate() throws Exception {\r\n        return new MongoTemplate( mongoDbFactory() );\r\n    }\r\n\r\n    @Bean\r\n    public IDocumentHierarchyService documentHierarchyService() throws Exception {\r\n        return new DocumentHierarchyService( mongoTemplate() );\r\n    }\r\n}\r\n<\/pre>\n<p>That&#8217;s pretty nice and clear. Thanks, <a href=\"http:\/\/www.springsource.org\/\">Spring<\/a> guys! Now, all boilerplate stuff is ready. Let&#8217;s move to interesting part: documents. Our database will contain &#8216;documents&#8217; collection which stores documents of type SimpleDocument. We describe this using <a href=\"http:\/\/www.springsource.org\/spring-data\/mongodb\">Spring Data MongoDB<\/a> annotations for SimpleDocument POJO.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: java;\">package com.example.mongodb.hierarchical;\r\n\r\nimport java.util.Collection;\r\nimport java.util.HashSet;\r\n\r\nimport org.springframework.data.annotation.Id;\r\nimport org.springframework.data.annotation.Transient;\r\nimport org.springframework.data.mongodb.core.mapping.Document;\r\nimport org.springframework.data.mongodb.core.mapping.Field;\r\n\r\n@Document( collection = \"documents\" )\r\npublic class SimpleDocument {\r\n    public static final String PATH_SEPARATOR = \".\";\r\n\r\n    @Id private String id;\r\n    @Field private String name;\r\n    @Field private String path;\r\n\r\n    \/\/ We won't store this collection as part of document but will build it on demand\r\n    @Transient private Collection&lt; SimpleDocument &gt; documents = new HashSet&lt; SimpleDocument &gt;();\r\n\r\n    public SimpleDocument() {\r\n    }\r\n\r\n    public SimpleDocument( final String id, final String name ) {\r\n        this.id = id;\r\n        this.name = name;\r\n        this.path = id;\r\n    }\r\n\r\n    public SimpleDocument( final String id, final String name, final SimpleDocument parent ) {\r\n        this( id, name );\r\n        this.path = parent.getPath() + PATH_SEPARATOR + id;\r\n    }\r\n\r\n    public String getId() {\r\n        return id;\r\n    }\r\n\r\n    public void setId(String id) {\r\n        this.id = id;\r\n    }\r\n\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    public void setName(String name) {\r\n        this.name = name;\r\n    }\r\n\r\n    public String getPath() {\r\n        return path;\r\n    }\r\n\r\n    public void setPath(String path) {\r\n        this.path = path;\r\n    }\r\n\r\n    public Collection&lt; SimpleDocument &gt; getDocuments() {\r\n        return documents;\r\n    }\r\n}<\/pre>\n<p>Let me explain few things here. First, magic property <strong>path<\/strong>: this is a key to construct and query through our hierarchy. Path contains identifiers of all document&#8217;s parents, usually divided by some kind of separator, in our case just <strong>. (dot)<\/strong>. Storing document hierarchical relationships in this way allows quickly build hierarchy, search and navigate. Second, notice transient <strong>documents<\/strong> collection: this non-persistent collection is constructed by persistent provider and contains all descendant documents (which, in case, also contain own descendants). Let see it in action by looking into <strong>find<\/strong> method implementation:<\/p>\n<pre class=\"brush: java;\">package com.example.mongodb.hierarchical;\r\n\r\nimport java.util.Arrays;\r\nimport java.util.Collection;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\nimport org.springframework.data.mongodb.core.MongoOperations;\r\nimport org.springframework.data.mongodb.core.query.Criteria;\r\nimport org.springframework.data.mongodb.core.query.Query;\r\n\r\npublic class DocumentHierarchyService {\r\n    private MongoOperations template;\r\n\r\n    public DocumentHierarchyService( final MongoOperations template ) {\r\n        this.template = template;\r\n    }\r\n\r\n    @Override\r\n    public SimpleDocument find( final String id ) {\r\n        final SimpleDocument document = template.findOne(\r\n            Query.query( new Criteria( \"id\" ).is( id ) ),\r\n            SimpleDocument.class\r\n        );\r\n\r\n        if( document == null ) {\r\n            return document;\r\n        }\r\n\r\n        return build(\r\n            document,\r\n            template.find(\r\n                Query.query( new Criteria( \"path\" ).regex( \"^\" + id + \"[.]\" ) ),\r\n                SimpleDocument.class\r\n            )\r\n        );\r\n    }\r\n\r\n    private SimpleDocument build( final SimpleDocument root, final Collection&lt; SimpleDocument &gt; documents ) {\r\n        final Map&lt; String, SimpleDocument &gt; map = new HashMap&lt; String, SimpleDocument &gt;();\r\n\r\n        for( final SimpleDocument document: documents ) {\r\n            map.put( document.getPath(), document );\r\n        }\r\n\r\n        for( final SimpleDocument document: documents ) {\r\n            map.put( document.getPath(), document );\r\n\r\n            final String path = document\r\n                .getPath()\r\n                .substring( 0, document.getPath().lastIndexOf( SimpleDocument.PATH_SEPARATOR ) );\r\n\r\n            if( path.equals( root.getPath() ) ) {\r\n                root.getDocuments().add( document );\r\n            } else {\r\n                final SimpleDocument parent = map.get( path );\r\n                if( parent != null ) {\r\n                    parent.getDocuments().add( document );\r\n                }\r\n            }\r\n        }\r\n\r\n        return root;\r\n    }\r\n}\r\n<\/pre>\n<p>As you can see, to get single document with a whole hierarchy we need to run just two queries (but more optimal algorithm could reduce it to just one single query). Here is a sample hierarchy and the the result of reading root document from <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a><\/p>\n<pre class=\"brush: java;\">template.dropCollection( SimpleDocument.class );\r\n\r\nfinal SimpleDocument parent = new SimpleDocument( \"1\", \"Parent 1\" );\r\nfinal SimpleDocument child1 = new SimpleDocument( \"2\", \"Child 1.1\", parent );\r\nfinal SimpleDocument child11 = new SimpleDocument( \"3\", \"Child 1.1.1\", child1 );\r\nfinal SimpleDocument child12 = new SimpleDocument( \"4\", \"Child 1.1.2\", child1 );\r\nfinal SimpleDocument child121 = new SimpleDocument( \"5\", \"Child 1.1.2.1\", child12 );\r\nfinal SimpleDocument child13 = new SimpleDocument( \"6\", \"Child 1.1.3\", child1 );\r\nfinal SimpleDocument child2 = new SimpleDocument( \"7\", \"Child 1.2\", parent );\r\n\r\ntemplate.insertAll( Arrays.asList( parent, child1, child11, child12, child121, child13, child2 ) );\r\n\r\n...\r\n\r\nfinal ApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class );\r\nfinal IDocumentHierarchyService service = context.getBean( IDocumentHierarchyService.class );\r\n\r\nfinal SimpleDocument document = service.find( \"1\" );\r\n\/\/  Printing document show following hierarchy:\r\n\/\/\r\n\/\/  Parent 1\r\n\/\/   |-- Child 1.1\r\n\/\/     |-- Child 1.1.1\r\n\/\/     |-- Child 1.1.3\r\n\/\/     |-- Child 1.1.2\r\n\/\/       |-- Child 1.1.2.1\r\n\/\/   |-- Child 1.2\r\n<\/pre>\n<p>That&#8217;s it. Simple a powerful concept. Sure, adding index on a <strong>path<\/strong> property will speed up query significantly. There are a plenty of improvements and optimizations but basic idea should be clear now.<\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/aredko.blogspot.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html\">Storing hierarchical data in MongoDB<\/a>&nbsp;from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a>&nbsp;Andrey Redko at the&nbsp;<a href=\"http:\/\/aredko.blogspot.com\/\">Andriy Redko {devmind} <\/a>blog.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations. MongoDB is awesome document data store but what if documents have parent-child relationships? Can we effectively store and query such document hierarchies? The answer, for sure, is yes, we can. MongoDB has &hellip;<\/p>\n","protected":false},"author":141,"featured_media":187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[112],"class_list":["post-792","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-mongodb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Storing hierarchical data in MongoDB - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.\" \/>\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.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Storing hierarchical data in MongoDB - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-01-27T19:13:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T22:39:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"Storing hierarchical data in MongoDB\",\"datePublished\":\"2012-01-27T19:13:00+00:00\",\"dateModified\":\"2012-10-21T22:39:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html\"},\"wordCount\":411,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"keywords\":[\"MongoDB\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html\",\"name\":\"Storing hierarchical data in MongoDB - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"datePublished\":\"2012-01-27T19:13:00+00:00\",\"dateModified\":\"2012-10-21T22:39:28+00:00\",\"description\":\"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/01\\\/storing-hierarchical-data-in-mongodb.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Storing hierarchical data in MongoDB\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Storing hierarchical data in MongoDB - Java Code Geeks","description":"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.","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.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html","og_locale":"en_US","og_type":"article","og_title":"Storing hierarchical data in MongoDB - Java Code Geeks","og_description":"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.","og_url":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-01-27T19:13:00+00:00","article_modified_time":"2012-10-21T22:39:28+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"Storing hierarchical data in MongoDB","datePublished":"2012-01-27T19:13:00+00:00","dateModified":"2012-10-21T22:39:28+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html"},"wordCount":411,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","keywords":["MongoDB"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html","url":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html","name":"Storing hierarchical data in MongoDB - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","datePublished":"2012-01-27T19:13:00+00:00","dateModified":"2012-10-21T22:39:28+00:00","description":"Continuing NoSQL journey with MongoDB, I would like to touch one specific use case which comes up very often: storing hierarchical document relations.","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/01\/storing-hierarchical-data-in-mongodb.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Storing hierarchical data in MongoDB"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=792"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/792\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/187"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}