While schema-free databases, like DocumentDB, make it extremely good smooth to embody modifications in your facts model, you need to still spend a while considering your records.
- You have a whole lot of alternatives. Naturally, you could simply paintings JSON object graphs or even uncooked strings of JSON textual content, however you could also use dynamic gadgets that helps you to bind to homes at runtime without defining a class at compile time.
- You can also paintings with actual C# gadgets, or Entities as they may be called, which might be your enterprise area training.
Relationships
Let’s take a look at the document's hierarchal structure. It has a few pinnacle-stage homes just like the required identification, as well as lastName and isRegistered, but it additionally has nested properties.
{
"id": "AndersenFamily",
"lastName": "Andersen",
"parents": [
{ "firstName": "Thomas", "relationship": "father" },
{ "firstName": "Mary Kay", "relationship": "mother" }
],
"children": [
{
"firstName": "Henriette Thaulow",
"gender": "female",
"grade": 5,
"pets": [ { "givenName": "Fluffy", "type": "Rabbit" } ]
}
],
"location": { "state": "WA", "county": "King", "city": "Seattle"},
"isRegistered": true
}
- For instance, the parents property is provided as a JSON array as denoted by using the square brackets.
- We additionally have another array for youngsters, despite the fact that there may be handiest one baby inside the array in this case. So that is the way you model the equivalent of 1-to-many relationships inside a report.
- You surely use arrays where every detail within the array can be a simple price or another complex object, even another array.
- So one own family can have a couple of parents and more than one kids and if you observe the kid items, they have a puppy’s property this is itself a nested array for a oneto-many relationship among children and pets.
- For the region belongings, we are combining 3 associated residences, the kingdom, county, and city into an object.
- Embedding an item this manner in place of embedding an array of objects is just like having a one-to-one dating among rows in separate tables in a relational database.
Embedding Data
When you begin modeling records in a report store, including DocumentDB, attempt to treat your entities as self-contained documents represented in JSON. When working with relational databases, we constantly normalize information.
- Normalizing your records typically involves taking an entity, which include a consumer, and breaking it down into discreet portions of facts, like contact details and addresses.
- To read a purchaser, with all their touch info and addresses, you need to use JOINS to efficiently mixture your records at run time.
Now allow's take a look at how we would version the equal records as a self-contained entity in a document database.
{
"id": "1",
"firstName": "Mark",
"lastName": "Upston",
"addresses": [
{
"line1": "232 Main Street",
"line2": "Unit 1",
"city": "Brooklyn",
"state": "NY",
"zip": 11229
}
],
"contactDetails": [
{"email": "mark.upston@xyz.com"},
{"phone": "+1 356 545-86455", "extension": 5555}
]
}
As you could see that we've got denormalized the customer report wherein all of the records of the consumer is embedded into a single JSON document.
In NoSQL we've got a unfastened schema, so you can upload contact information and addresses in one of a kind format as nicely. In NoSQL, you could retrieve a client record from the database in a unmarried read operation. Similarly, updating a file is also a unmarried write operation.
Following are the stairs to create documents using .Net SDK.
Step 1 − Instantiate DocumentClient. Then we will query for the myfirstdb database and additionally question for MyCollection series, which we store on this personal variable collection so that is it's available in the course of the magnificence.
private static async Task CreateDocumentClient() {
// Create a new instance of the DocumentClient
using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) {
database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
'myfirstdb'").AsEnumerable().First();
collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
"SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();
await CreateDocuments(client);
}
}
Step 2 − Create some documents in CreateDocuments venture.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
},
postalCode = "11229", countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
}
The first document can be generated from this dynamic item. This would possibly appear like JSON, however of route it isn't. This is C# code and we are growing a actual .NET object, but there is no magnificence definition. Instead the properties are inferred from the way the item is initialized. You can word additionally that we haven't provided an Id assets for this report.
Step 3 − Now let's take a look at the CreateDocument and it seems like the equal pattern we noticed for developing databases and collections.
private async static Task<Document> CreateDocument(DocumentClient client,
object documentObject) {
var result = await client.CreateDocumentAsync(collection.SelfLink, documentObject);
var document = result.Resource;
Console.WriteLine("Created new document: {0}\r\n{1}", document.Id, document);
return result;
}
Step 4 − This time we name CreateDocumentAsync specifying the SelfLink of the collection we need to add the record to. We get returned a response with a useful resource belongings that, in this example, represents the new document with its system-generated houses.
In the following CreateDocuments venture, we've created three files.
- In the primary report, the Document item is a described elegance inside the SDK that inherits from resource and so it has all the commonplace aid residences, however it's also the dynamic homes that define the schema-free file itself.
private async static Task CreateDocuments(DocumentClient client) {
Console.WriteLine();
Console.WriteLine("**** Create Documents ****");
Console.WriteLine();
dynamic document1Definition = new {
name = "New Customer 1", address = new {
addressType = "Main Office",
addressLine1 = "123 Main Street",
location = new {
city = "Brooklyn", stateProvinceName = "New York"
},
postalCode = "11229",
countryRegionName = "United States"
},
};
Document document1 = await CreateDocument(client, document1Definition);
Console.WriteLine("Created document {0} from dynamic object", document1.Id);
Console.WriteLine();
var document2Definition = @" {
""name"": ""New Customer 2"",
""address"": {
""addressType"": ""Main Office"",
""addressLine1"": ""123 Main Street"",
""location"": {
""city"": ""Brooklyn"", ""stateProvinceName"": ""New York""
},
""postalCode"": ""11229"",
""countryRegionName"": ""United States""
}
}";
Document document2 = await CreateDocument(client, document2Definition);
Console.WriteLine("Created document {0} from JSON string", document2.Id);
Console.WriteLine();
var document3Definition = new Customer {
Name = "New Customer 3",
Address = new Address {
AddressType = "Main Office",
AddressLine1 = "123 Main Street",
Location = new Location {
City = "Brooklyn", StateProvinceName = "New York"
},
PostalCode = "11229",
CountryRegionName = "United States"
},
};
Document document3 = await CreateDocument(client, document3Definition);
Console.WriteLine("Created document {0} from typed object", document3.Id);
Console.WriteLine();
}
- This 2nd record simply works with a raw JSON string. Now we step into an overload for CreateDocument that uses the JavaScriptSerializer to de-serialize the string into an item, which it then passes directly to the identical CreateDocument method that we used to create the primary document.
- In the 0.33 document, we have used the C# object Customer which is defined in our software.
Let’s take a look at this customer, it has an Id and address assets where the address is a nested item with its own homes which include area, which is yet any other nested item.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DocumentDBDemo {
public class Customer {
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
// Must be nullable, unless generating unique values for new customers on client
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "address")]
public Address Address { get; set; }
}
public class Address {
[JsonProperty(PropertyName = "addressType")]
public string AddressType { get; set; }
[JsonProperty(PropertyName = "addressLine1")]
public string AddressLine1 { get; set; }
[JsonProperty(PropertyName = "location")]
public Location Location { get; set; }
[JsonProperty(PropertyName = "postalCode")]
public string PostalCode { get; set; }
[JsonProperty(PropertyName = "countryRegionName")]
public string CountryRegionName { get; set; }
}
public class Location {
[JsonProperty(PropertyName = "city")]
public string City { get; set; }
[JsonProperty(PropertyName = "stateProvinceName")]
public string StateProvinceName { get; set; }
}
}
We additionally have JSON property attributes in area due to the fact we want to hold proper conventions on each facets of the fence.
So I just create my New Customer object together with its nested infant items and contact into CreateDocument yet again. Although our client object does have an Id assets we did not supply a fee for it and so DocumentDB generated one based on the GUID, similar to it did for the preceding two files.
When the above code is compiled and achieved you'll acquire the subsequent output.
**** Create Documents ****
Created new document: 575882f0-236c-4c3d-81b9-d27780206b2c
{
"name": "New Customer 1",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"id": "575882f0-236c-4c3d-81b9-d27780206b2c",
"_rid": "kV5oANVXnwDGPgAAAAAAAA==",
"_ts": 1450037545,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDGPgAAAAAAAA==/",
"_etag": "\"00006fce-0000-0000-0000-566dd1290000\"",
"_attachments": "attachments/"
}
Created document 575882f0-236c-4c3d-81b9-d27780206b2c from dynamic object
Created new document: 8d7ad239-2148-4fab-901b-17a85d331056
{
"name": "New Customer 2",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"id": "8d7ad239-2148-4fab-901b-17a85d331056",
"_rid": "kV5oANVXnwDHPgAAAAAAAA==",
"_ts": 1450037545,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDHPgAAAAAAAA==/",
"_etag": "\"000070ce-0000-0000-0000-566dd1290000\"",
"_attachments": "attachments/"
}
Created document 8d7ad239-2148-4fab-901b-17a85d331056 from JSON string
Created new document: 49f399a8-80c9-4844-ac28-cd1dee689968
{
"id": "49f399a8-80c9-4844-ac28-cd1dee689968",
"name": "New Customer 3",
"address": {
"addressType": "Main Office",
"addressLine1": "123 Main Street",
"location": {
"city": "Brooklyn",
"stateProvinceName": "New York"
},
"postalCode": "11229",
"countryRegionName": "United States"
},
"_rid": "kV5oANVXnwDIPgAAAAAAAA==",
"_ts": 1450037546,
"_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDIPgAAAAAAAA==/",
"_etag": "\"000071ce-0000-0000-0000-566dd12a0000\"",
"_attachments": "attachments/"
}
Created document 49f399a8-80c9-4844-ac28-cd1dee689968 from typed object