{"id":1728,"date":"2011-06-30T19:35:32","date_gmt":"2011-06-30T18:35:32","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=1728"},"modified":"2021-08-24T13:28:36","modified_gmt":"2021-08-24T12:28:36","slug":"ravendb-documents","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2011\/06\/ravendb-documents\/","title":{"rendered":"RavenDB: Documents, Nothing But Documents"},"content":{"rendered":"<p>Last time we\u2019ve made the <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/06\/first-steps-with-reavendb\/\">first steps with RavenDB<\/a>. I\u2019ve already mentioned that RavenDB is a document database (see also <a href=\"http:\/\/en.wikipedia.org\/wiki\/Document-oriented_database\">Wikipedia<\/a>). However in our examples we just stored objects. So where are the documents?<\/p>\n<h2>Object to JSON Document<\/h2>\n<p>What does happen when we pass an object to the session\u2019s store-method? Well under the cover the RavenDB client library serializes that object to a JSON document. So your object graph is converted into a document.<\/p>\n<div id=\"attachment_1736\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/documents.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1736\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/documents-300x163.png\" alt=\"Documents, Nothing But Documents\" title=\"documents\" class=\"size-medium wp-image-1736\" width=\"300\" height=\"163\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/documents-300x163.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/documents.png 600w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1736\" class=\"wp-caption-text\">Documents, Nothing But Documents<\/p><\/div>\n<p>That has a few implications. A document is a hierarchical data structure. Therefore your object should be hierarchically structured and shouldn\u2019t contain any circular references. If you try to store an object with circular references you will get an exception.<\/p>\n<p>When you pass in an object which references other objects then all referenced objects are serialized to a single document. What does that mean for us? Well it means that the child-objects are not separate \u2018units-of-storage\u2019 in the database. You can only access the document and then peek into it. Let me demonstrate this with a simple example. We store persons with the city their living in. For this we create a person and a city class. Then we store a person with its city. Now we can easily query for persons, but not the city. The reason is that the city was embedded in to person document and therefore there\u2019s no city document.<br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=Documents-Demo.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">using (var session = documentStore.OpenSession())\n{\n        \/\/ We store a person and its city\n\tsession.Store(new Person(&quot;Gamlor&quot;,new City(&quot;Vals&quot;)));\n\tsession.SaveChanges();\n}\nusing (var session = documentStore.OpenSession())\n{\n        \/\/ We can get the person, because it's in a person document\n\tvar hasPeopleInDB = session.Query&lt;Person&gt;().Any();\n\tConsole.Out.WriteLine(&quot;Do we have people-documents in the db? {0}&quot;,\n\t\thasPeopleInDB ? &quot;Yes, we do&quot; : &quot;No, we dont&quot;);\n        \/\/ However the city isn't in its own document\n\tvar hasCitiesInDB = session.Query&lt;City&gt;().Any();\n\tConsole.Out.WriteLine(&quot;Do we have city-documents in the db? {0}&quot;,\n\t\thasCitiesInDB ? &quot;Yes, we do&quot; : &quot;No, we dont&quot;);\n}<\/code><\/pre><\/noscript><\/p>\n<h2>Document-Design<\/h2>\n<p>We\u2019ve seen that RavenDB stores documents. Now the question is how we split our domain model across different documents. The general rule of thumb is to split your documents in such a way up that they fit together with the operations. By that I mean that operations in your application don\u2019t have to meddle with hundreds of documents. Instead a document should contain all the data which are needed for the most common operations.<\/p>\n<div id=\"attachment_1738\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/doc-design.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1738\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/doc-design-300x213.png\" alt=\"Document Design\" title=\"doc-design\" class=\"size-medium wp-image-1738\" width=\"300\" height=\"213\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/doc-design-300x213.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/doc-design.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1738\" class=\"wp-caption-text\">Document Design<\/p><\/div>\n<p>Let\u2019s look at an example, an oversimplified online shop. We store costumers, orders and order-items:<\/p>\n<div id=\"attachment_1739\" style=\"width: 510px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/domainmodel.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1739\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/domainmodel.png\" alt=\"Our Entity Model\" title=\"domainmodel\" class=\"size-full wp-image-1739\" width=\"500\" height=\"141\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/domainmodel.png 500w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/domainmodel-300x84.png 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/a><p id=\"caption-attachment-1739\" class=\"wp-caption-text\">Our Entity Model<\/p><\/div>\n<p>Now how do we split that up? Everything in one document? Each entity in its own document? Well let\u2019s think about it what operations we do in a shop and which entities we manipulate in those operations:<\/p>\n<ul>\n<li>Registering customer \u2013&gt; customer entity<\/li>\n<li>Changing customer data \u2013&gt; customer entity<\/li>\n<li>New \u2018shopping\u2019-tour \u2013&gt; order entity<\/li>\n<li>Adding and removing item \u2013&gt; order and order-item entity<\/li>\n<li>Showing shopping list \u2013&gt; order and order-item entity<\/li>\n<li>Send the order \/ finish shopping \u2013&gt; order and order-item entity<\/li>\n<\/ul>\n<p>After taking a look at the operation it looks like that either the customer entity is touched or the order together with order-item entity. Therefore I suggest storing the customer in a document and the order with its order entities in a document.<\/p>\n<h2>Referencing Documents<\/h2>\n<p>We\u2019ve decided to split up our entities in multiple documents. But how do we reference documents to each other? Well that\u2019s done by storing the id of the referenced document. Each document has an id by which it can be referenced. When your entity has a property \u2018Id\u2019 RavenDB will by convention put the id there. That way we get the id of a document and use it for references. Like in this example, where the order references the customer by its id. (Here are the <a href=\"https:\/\/gist.github.com\/1054829#file_shop_model.cs\">entity-classes for the example<\/a>)<br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=CreateReferenceToOtherDoc.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var customer = new Customer(&quot;Gamlor&quot;);\nsession.Store(customer);\n\n\/\/ After storing we have a valid id\nvar firstOrder = new Order()\n\t\t\t{\n\t\t\t\tCustomerId = costumer.Id\n\t\t\t};\nfirstOrder.AddToOrder(new OrderItem(&quot;Magic Unicorn&quot;));\nsession.Store(firstOrder);\n\nsession.SaveChanges();<\/code><\/pre><\/noscript><\/p>\n<p>Later on we can load the referenced documents by id. However we should remind our self that when possible operations should be able to more or less operate on one document. If we load hundreds of documents by reference we are doing something wrong or our problem is a bad fit for a document database.<br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=LoadById.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var order = session.Query&lt;Order&gt;().First();\nvar costumer = session.Load&lt;Customer&gt;(order.CustomerId);<\/code><\/pre><\/noscript><\/p>\n<div id=\"attachment_1741\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/references.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1741\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/references-300x175.png\" alt=\"References to Other Documents\" title=\"references\" class=\"size-medium wp-image-1741\" width=\"300\" height=\"175\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/references-300x175.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/references.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1741\" class=\"wp-caption-text\">References to Other Documents<\/p><\/div>\n<h2>Batch-Loading Referenced Documents<\/h2>\n<p>Of course in reality there will be places where we need to load referenced documents. The code above creates an additional round trip to the database to load the referenced document. Network round trips are costly, that\u2019s why we might want to get referenced documents in one go. We can do this by explicitly telling RavenDB to include referenced documents. Like this:<br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=BachLoad.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var order = session.Query&lt;Order&gt;()\n   .Customize(x =&gt; x.Include&lt;Order&gt;(o=&gt;o.CustomerId)) \/\/ Load also the costumer\n   .First();\nvar customer = session.Load&lt;Customer&gt;(order.CustomerId);<\/code><\/pre><\/noscript><\/p>\n<div id=\"attachment_1743\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/batch-load.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1743\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/batch-load-300x205.png\" alt=\"Batch Load Documents\" title=\"batch-load\" class=\"size-medium wp-image-1743\" width=\"300\" height=\"205\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/batch-load-300x205.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/batch-load.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1743\" class=\"wp-caption-text\">Batch Load Documents<\/p><\/div>\n<h2>Don\u2019t fear the Demoralization<\/h2>\n<p>As you might already noticed documents are not normalized! We pack things together in a document and some data are redundantly stored. For example when we store blog-posts we certainly embed the tags in the same document. Above we\u2019ve taken a look at references. Often we\u2019ve the issue that we need only a few things from a referenced document. For example in our web shop we want to show the user name for current order we are piling together. Instead of loading the referenced costumer document every time we just could store this information redundantly in our order document.<\/p>\n<div id=\"attachment_1745\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/denormalisation.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1745\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/denormalisation-300x225.png\" alt=\"Denormalisation by Copying Information\" title=\"denormalisation\" class=\"size-medium wp-image-1745\" width=\"300\" height=\"225\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/denormalisation-300x225.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/06\/denormalisation.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1745\" class=\"wp-caption-text\">Denormalisation by Copying Information<\/p><\/div>\n<p>For example we can create a class which holds the id and a name. This class is used to represent a reference to another document, but also copies the name of that document. That way we don\u2019t need to do any document lookup as long as we only need the name:<br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=ModelWithDenormalizedReference.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">public interface INamedObject\n{\n\tstring Id { get; set; }\n\tstring Name { get; set; }\n}\n\ninternal class Customer : INamedObject\n{\n\tpublic Customer(string name)\n\t{\n\t\tName = name;\n\t}\n\tpublic string Id { get; set; }\n\tpublic string Name { get; set; }\n\tpublic string Address { get; set; }\n}\n\ninternal class Order\n{\n\tpublic Order()\n\t{\n\t\tItems = new List&lt;OrderItem&gt;();\n\t}\n\tpublic string Id { get; set; }\n\tpublic DenormalizedReference&lt;Customer&gt; CustomerReference { get; set; }\n\tpublic IList&lt;OrderItem&gt; Items { get; private set; }\n}\n\/\/ Denormalized reference, which stores the name of the named object.\npublic class DenormalizedReference&lt;T&gt; where T : INamedObject\n{\n\tpublic string Id { get; set; }\n\tpublic string Name { get; set; }\n\n\tpublic static implicit operator DenormalizedReference&lt;T&gt;(T doc)\n\t{\n\t\treturn new DenormalizedReference&lt;T&gt;\n\t\t\t\t   {\n\t\t\t\t\t   Id = doc.Id,\n\t\t\t\t\t   Name = doc.Name\n\t\t\t\t   };\n\t}\n}<\/code><\/pre><\/noscript><br \/>\n<script src=\"https:\/\/gist.github.com\/1054829.js?file=StoringWithDenormalizedReference.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">var customer = new Customer(&quot;Gamlor&quot;);\nsession.Store(customer);\n\nvar firstOrder = new Order()\n\t\t\t {\n\t\t\t\t \/\/ This is automatically converted to a named-reference\n                                 \/\/ due to the magic of the implicit cast operator.\n                                 \/\/ Now the order has the id and the name of the customer document\n\t\t\t\t CustomerReference = customer \n\t\t\t };\nfirstOrder.AddToOrder(new OrderItem(&quot;Magic Unicorn&quot;));\nsession.Store(firstOrder);\n\n\/\/ Later on:\nvar order = session.Query&lt;Order&gt;().First();\n\/\/ no need for loading the customer document as long as we only need the name\nvar customerName = order.CustomerReference.Name;\nConsole.Out.WriteLine(customerName);<\/code><\/pre><\/noscript><\/p>\n<h2>Conclusion &amp; Next Time<\/h2>\n<p>This time we\u2019ve looked at documents and how we can split up data in different documents. Next time we will look at RavenDB\u2019s queries and indexes because they behave quite differently than in most databases.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time we\u2019ve made the first steps with RavenDB. I\u2019ve already mentioned that RavenDB is a document database (see also Wikipedia). However in our examples we just stored objects. So&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126,231],"tags":[21,296],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1728"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1728"}],"version-history":[{"count":21,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1728\/revisions"}],"predecessor-version":[{"id":3909,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1728\/revisions\/3909"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1728"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1728"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1728"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}