<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Azure DocumentDB Team blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/documentdb/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/documentdb/feed.xml</link>
    <description>This blog is where the Azure DocumentDB team will share news about the product, code snippets / samples / tutorials and general information about the service.</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:20:37 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>We have moved ....</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/we-have-moved</link>
      <pubDate>Mon, 13 Jul 2015 11:32:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2015/07/13/we-have-moved/</guid>
      <description><![CDATA[As you may have noticed, the last blog post here was ages ago ... don't worry, we haven't died ......]]></description>
      <content:encoded><![CDATA[<p>As you may have noticed, the last blog post here was ages ago ... don't worry, we haven't died ... we have just moved.</p>
<p>In an effort to consolidate all Azure information in one place we have moved to <a title="Azure Blog" href="https://azure.microsoft.com/blog/">https://azure.microsoft.com/blog/</a>.<br />Don't worry, if you're looking for <span style="text-decoration: underline;">just </span>DocumentDB posts then you can filter for just DocumentDB posts by using tags - <a title="DocumentDB Posts" href="https://azure.microsoft.com/blog/tag/documentdb/">https://azure.microsoft.com/blog/tag/documentdb/</a>.</p>
<p>However, I encourage you to at least scan all the other posts as we are adding a ton of cool new features to Azure all the time.</p>
<p>You can still follow us on Twitter at @DocumentDB.</p>]]></content:encoded>
    </item>
    <item>
      <title>Searching for text with DocumentDB</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/searching-for-text-with-documentdb</link>
      <pubDate>Mon, 09 Mar 2015 19:39:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2015/03/09/searching-for-text-with-documentdb/</guid>
      <description><![CDATA[A common ask among DocumentDB customers is, &ldquo;How do I search for documents containing some...]]></description>
      <content:encoded><![CDATA[<p>A common ask among DocumentDB customers is, &ldquo;How do I search for documents containing some string value?&rdquo; In this post, will explore two different ways of doing this, depending on what you are trying to do.</p>
<h2>1. Tokenizing words</h2>
<p>The first method is easy to implement and works well when your requirements are relatively simple word matching. Consider a document that looks like the JSON below:</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{
    <span style="color: #006080;">"id"</span>: <span style="color: #006080;">"CDC101"</span>,
    <span style="color: #006080;">"title"</span>: <span style="color: #006080;">"Fundamentals of database design"</span>,&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #006080;">"credits"</span>:  10
}</pre>
<p>&nbsp;</p>
</div>
<p>How would I search for all documents that had the word &lsquo;database&rsquo; in the title field? A simple way to do this would be to tokenize the title field and create JSON as below:</p>
<div>
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{
    <span style="color: #006080;">"id"</span>: <span style="color: #006080;">"CDC101"</span>,
    <span style="color: #006080;">"title"</span>: <span style="color: #006080;">"Fundamentals of database design"</span>,
    <span style="color: #006080;">"titleWords"</span>: [ <span style="color: #006080;">"fundamentals"</span>, <span style="color: #006080;">"database"</span>, <span style="color: #006080;">"design"</span> ],
    <span style="color: #006080;">"credits"</span>:  10
}</pre>
</div>
<blockquote>
<div><span style="text-decoration: underline;">Note:</span>&nbsp; consider using a RegEx to transform words to lowercase and remove any punctuation. Also, strip out stop words like &ldquo;to&rdquo;, &ldquo;the&rdquo;, &ldquo;of&rdquo;&nbsp; etc. (<a title="https://en.wikipedia.org/wiki/Stop_words" href="https://en.wikipedia.org/wiki/Stop_words">https://en.wikipedia.org/wiki/Stop_words</a>)</div>
</blockquote>
<p>Now searching for words in the title becomes easy with the following query:</p>
<div>
<div>
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="font-family: calibri;"><span style="font-size: small;"><span style="color: #0000ff;">SELECT</span> r <span style="color: #0000ff;">FROM</span> root r <span style="color: #0000ff;">JOIN</span> word <span style="color: #0000ff;">IN</span> r.titleWords <span style="color: #0000ff;">WHERE</span> word = "database" </span></span></pre>
</div>
<p>&nbsp;</p>
<p>The query above is very efficient because it will take advantage of the fact that each word in the array will be indexed by default in DocumentDB allowing for quick equality matching as we are doing here. Another great advantage to this approach is that it will honor the consistency levels of your database meaning that any changes to your tokenized words will be available immediately.</p>
</div>
<h2>2. Using Azure Search</h2>
<p>If you have several words to tokenize, you accommodate the extra storage required to store the additional array of words, or you need more complex multi-faceted full-text searching capabilities across multiple fields etc. then the above approach will not work for you and you need the assistance of a more powerful full-text capable search engine. Luckily Azure has one of these that is super easy to setup and use, it is called <a href="https://azure.microsoft.com/en-us/services/search/" target="_blank">Azure Search</a>.</p>
<p>You can setup a data source pointing to your DocumentDB database and have a Search indexer crawl through your data on a predefined schedule.</p>
<p>For detailed steps on setting this up, check out <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-search-indexer/">Connecting DocumentDB with Azure Search using indexers</a>. You can also <a href="https://portalcontent.blob.core.windows.net/samples/searchabletodo.zip">download a sample</a> ASP.NET MVC web application using DocumentDB and Search together.</p>
<p>In order to run this sample, simply create a Search account and a DocumentDB account. Once you have these, update the web.config with your endpoints and keys (obtainable from the Azure Management Portal).</p>
<p>The download includes sample todo items which you can import in to DocumentDB if you want to start with some canned data, or you can just crack open the solution in Visual Studio and run the project to start with a clean slate.</p>
<p>Add some todo items, hit the index button to force a manual re-index and then go do some searching.</p>
<p>So, there you have it &ndash; &gt; Searching for text within DocumentDB is easy!</p>
<p>To learn more about DocumentDB, visit our <a href="https://azure.com/docdb">service page</a> and to learn more about DocumentDB query syntax, please visit our <a href="https://www.documentdb.com/sql/demo" target="_blank">Query Playground</a> page.</p>]]></content:encoded>
    </item>
    <item>
      <title>Performance Tips for Azure DocumentDB – Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/performance-tips-for-azure-documentdb-part-2</link>
      <pubDate>Mon, 26 Jan 2015 12:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2015/01/26/performance-tips-for-azure-documentdb-part-2/</guid>
      <description><![CDATA[Performance Tips for Azure DocumentDB &ndash; Part 2
Azure DocumentDB allows you to tune the...]]></description>
      <content:encoded><![CDATA[<p><strong>Performance Tips for Azure DocumentDB &ndash; Part 2</strong></p>
<p><a href="https://azure.com/docdb">Azure DocumentDB</a> allows you to tune the performance of your database to best meet the needs of your application.&nbsp; In <a href="https://azure.microsoft.com/blog/2015/01/20/performance-tips-for-azure-documentdb-part-1-2/">part 1</a> of this series, we looked at networking and SDK configuration options available in DocumentDB and their impact on performance. This post will continue the discussion and cover the performance impact of indexing policies, throughput optimization and consistency levels.&nbsp; Like any performance tuning recommendation, not every one of these tips may be applicable for your use case, but you can use this information as a guide in order to assist you in making the right design choices for your applications.</p>
<p><strong>INDEXING POLICY</strong></p>
<p><strong>Indexing Policy Tip #1: Use lazy indexing for faster peak time ingestion rates</strong></p>
<p>DocumentDB allows you to specify &ndash; at the collection level &ndash; an indexing policy, which enables you to choose if you want the documents in a collection to be automatically indexed or not.&nbsp; In addition, you may also choose between synchronous (Consistent) and asynchronous (Lazy) index updates. By default, the index is updated synchronously on each insert, replace or delete of a document to the collection. This enables the queries to honor the same <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-consistency-levels/">consistency level</a> as that of the document reads without any delay for the index to &ldquo;catch up".</p>
<p>Lazy indexing may be considered for scenarios in which data is written in bursts, and you want to amortize the work required to index content over a longer period of time. This allows you to use your provisioned throughput effectively and serve write requests at peak times with minimal latency. It is important to note, however, that when lazy indexing is enabled, query results will be eventually consistent regardless of the consistency level configured for the DocumentDB account.</p>
<p>Hence, Consistent indexing mode (IndexingPolicy.IndexingMode is set to Consistent) incurs the highest request unit charge per write, while Lazy indexing mode (IndexingPolicy.IndexingMode is set to Lazy) and no indexing (IndexingPolicy.Automatic is set to False) have zero indexing cost at the time of write.</p>
<p><strong>Indexing Policy Tip</strong><strong> #2: Exclude unused paths from indexing for faster writes</strong></p>
<p>DocumentDB&rsquo;s indexing policy also allows you to specify which document paths to include or exclude from indexing by leveraging Indexing Paths (IndexingPolicy.IncludedPaths and IndexingPolicy.ExcludedPaths). The use of indexing paths can offer improved write performance and lower index storage for scenarios in which the query patterns are known beforehand, as indexing costs are directly correlated to the number of unique paths indexed.&nbsp; For example:</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #008000;">//exclude index paths</span><br /><br />collection.IndexingPolicy.ExcludedPaths.Add(<span style="color: #006080;">"/\"metaData\"/*"</span>); collection.IndexingPolicy.ExcludedPaths.Add(<span style="color: #006080;">"/\"subDoc\"/\"subSubDoc\"/\"someProperty\"/*"</span>);<br />collection = await client.CreateDocumentCollectionAsync(databaseLink, collection);</pre>
</div>
<p><strong>Indexing Policy </strong><strong>Tip #3: Specify range index path type for all paths used in range queries</strong></p>
<p>DocumentDB currently supports two index path types: Hash and Range. Choosing an index path type of Hash enables efficient equality queries. Choosing an index type of Range enables range queries (using &gt;, &lt;, &gt;=, &lt;=).&nbsp;&nbsp; For example:</p>
<div id="codeSnippetWrapper"><br />
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">var collection = <span style="color: #0000ff;">new</span> DocumentCollection<br />{<br />    Id = ConfigurationManager.AppSettings[<span style="color: #006080;">"CollectionId"</span>]<br />};<br /><br />collection.IndexingPolicy.IncludedPaths.Add(<span style="color: #0000ff;">new</span> IndexingPath<br />{<br />    IndexType = IndexType.Hash,<br />    Path = <span style="color: #006080;">"/"</span>,<br />});<br /><br />collection.IndexingPolicy.IncludedPaths.Add(<span style="color: #0000ff;">new</span> IndexingPath<br />{<br />    IndexType = IndexType.Range,<br />    Path = <span style="color: #006080;">@"/"</span><span style="color: #006080;">"shippedTimestamp"</span><span style="color: #006080;">"/?"</span>,<br />    NumericPrecision = 7<br />});<br /><br />collection = await client.CreateDocumentCollectionAsync(databaseLink, collection);</pre>
</div>
</div>
<p><strong>Indexing Policy </strong><strong>Tip #4: Vary index precision for write vs query performance vs storage tradeoffs</strong></p>
<p>Finally, indexing policies allow you to change the index path precision in bytes to improve query performance. Queries against a path indexed with a higher precision are typically faster, but incur a correspondingly higher storage overhead for the index. Conversely, choosing a lower precision means that more documents might have to be processed during query execution, but the storage overhead will be lower.</p>
<p>For more details on indexing policies, refer to <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-indexing-policies/">this</a> documentation.</p>
<p><strong>Note:</strong> Currently in the Preview release the index policy for a collection can only be specified when a collection is created.</p>
<p><strong>Throughput</strong></p>
<p><strong>Throughput Tip #1: Measure and Tune for lower request units/second usage</strong></p>
<p>DocumentDB offers a rich set of database operations including relational and hierarchical queries with UDFs, stored procedures and triggers &ndash; all operating on the documents within a database collection. The cost associated with each of these operations will vary based on the CPU, IO and memory required to complete the operation. Instead of thinking about and managing hardware resources, you can think of a request unit (RU) as a single measure for the resources required to perform various database operations and service an application request.</p>
<p>Request units are provisioned for each Database Account based on the number of capacity units that you purchase. Request unit consumption is evaluated as a rate per second. Applications that exceed the provisioned request unit rate for their account will be throttled until the rate drops below the reserved level for the Account. If your application requires a higher level of throughput, you can purchase additional capacity units.</p>
<p>The complexity of a query impacts how many Request Units are consumed for an operation. The number of predicates, nature of the predicates, number of UDFs, and the size of the source data set all influence the cost of query operations.</p>
<p>To measure the overhead of any operation (create, update or delete), inspect the <strong>x-ms-request-charge </strong>header (or the equivalent RequestCharge property in ResourceResponse&lt;T&gt; or FeedResponse&lt;T&gt; in the .NET SDK) to measure the number of request units consumed by these operations.</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #008000;">// Measure the performance (request units) of writes</span><br /><br />ResourceResponse&lt;Document&gt; response = await client.CreateDocumentAsync(collectionSelfLink, myDocument);<br /><br />Console.WriteLine(<span style="color: #006080;">"Insert of document consumed {0} request units"</span>, response.RequestCharge);<br /><br /><span style="color: #008000;">// Measure the performance (request units) of queries</span><br /><br />IDocumentQuery&lt;dynamic&gt; queryable = client.CreateDocumentQuery(collectionSelfLink, queryString).AsDocumentQuery();<br /><br /><span style="color: #0000ff;">while</span> (queryable.HasMoreResults)<br />{<br /><br />    FeedResponse&lt;dynamic&gt; queryResponse = await queryable.ExecuteNextAsync&lt;dynamic&gt;();<br /><br />    Console.WriteLine(<span style="color: #006080;">"Query batch consumed {0} request units"</span>, queryResponse.RequestCharge);<br />}</pre>
</div>
<p>The request charge returned in this header is a fraction of your provisioned throughput (i.e. 2000 RUs / second).&nbsp;&nbsp; For example, if the query above returns 1000 1KB documents, the cost of the operation will be 1000. As such, within one second, the server will honor only two such requests before throttling subsequent requests.</p>
<p><strong>Throughput Tip #2: Handle Server throttles/request rate too large&nbsp; </strong></p>
<p>When a client attempts to exceed the reserved throughput for an account, there will be no performance degradation at the server and no use of throughput capacity beyond the reserved level. The server will preemptively end the request with RequestRateTooLarge (HTTP status code 429) and return the x-ms-retry-after-ms header indicating the amount of time, in milliseconds, that the user must wait before reattempting the request.</p>
<p>HTTP Status 429, <br />Status Line: RequestRateTooLarge <br />x-ms-retry-after-ms :100</p>
<p>If you are using the .NET Client SDK and LINQ queries, then most of the time you never have to deal with this exception, as the current version of the .NET Client SDK implicitly catches this response, respects the server-specified retry-after header, and retries the request. Unless your account is being accessed concurrently by multiple clients, the next retry will succeed.</p>
<p>If you have more than one client cumulatively operating consistently above the request rate, the default retry currently set to 3 by the .NET client may not suffice; in this case, the client will throw a DocumentClientException with status code 429 to the application. Note that with the current release of the .NET SDK, there is no way to turn off the default retry count.</p>
<p>While the automated retry behavior helps to improve resiliency and usability for the most applications, it might come at odds when doing performance benchmarks, especially when measuring latency.&nbsp; The client-observed latency will spike if the experiment hits the server throttle and causes the client SDK to silently retry. To avoid latency spikes during performance experiments, measure the charge returned by each operation and ensure that requests are operating below the reserved request rate.</p>
<p><strong>Throughput Tip #3: Delete empty collections to utilize all provisioned throughput</strong></p>
<p>Every document collection created in a DocumentDB account is allocated reserved throughput capacity based on the number of Capacity Units (CUs) provisioned, and the number of collections created.&nbsp;&nbsp; A single CU makes available 2,000 request units (RUs) and supports up to 3 collections. If only one collection is created for the CU, the entire CU throughput will be available for the collection. Once a second collection is created, the throughput of the first collection will be halved and given to the second collection, and so on. By provisioning additional CUs, the throughput for an existing collection can be increased. During DocumentDB Preview, a single collection can scale up to 10 GB and can be allocated up to the maximum throughput of a single CU, which is 2000 request units/second. To maximize the throughput available per collections, ensure that the number of capacity units to collections is 1:1.</p>
<p><strong>Throughput Tip #4: Design for smaller documents for higher throughput</strong></p>
<p>The Request Charge (i.e. request processing cost) of a given operation is directly correlated to the size of the document. Operations on large documents cost more than operations for small documents.</p>
<p><strong>CONSISTENCY LEVELS</strong></p>
<p><strong>Consistency Levels Tip #1: Use Weaker Consistency Levels for better Read latencies</strong></p>
<p>Another important factor to take into account while tuning the performance of a DocumentDB applications is Consistency Level. The choice of consistency Level has performance implications for both reads and writes. You can configure the Default Consistency Level on the database account and the chosen Consistency Level then applies to all the collections (across all of the databases) within the DocumentDB account. In terms of write operations, the impact of changing consistency level is observed as request latency. As stronger consistency levels are used, <em>write</em> latencies will increase. On the other hand, the impact of consistency level on <em>read</em> operations is observed in terms of throughput. Weaker consistency levels allow higher read throughput to be realized by the client.</p>
<p>By default all reads and queries issued against the user defined resources will use the default consistency level specified on the database account. You can, however, lower the consistency level of a specific read/query request by specifying the x-ms-consistency-level<strong> </strong>request header.</p>
<p><strong>WRAPPING UP</strong></p>
<p>We hope that between this post and <a href="https://azure.microsoft.com/blog/2015/01/20/performance-tips-for-azure-documentdb-part-1-2/">part 1</a> you&rsquo;ve found performance tips which are both useful and applicable to your usage of DocumentDB.&nbsp;</p>
<p>As always, we&rsquo;d love to hear from you about the DocumentDB features and experiences you would find most valuable.&nbsp;</p>
<p>Please submit your suggestions on the Microsoft Azure DocumentDB <a href="https://feedback.azure.com/forums/263030-documentdb?filter=top&amp;page=1">feedback forum</a>.&nbsp;</p>
<p>If you haven&rsquo;t tried DocumentDB yet, then get started <a href="https://azure.microsoft.com/en-us/services/documentdb/">here</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Announcing SQL Parameterization in DocumentDB</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/announcing-sql-parameterization-in-documentdb</link>
      <pubDate>Wed, 14 Jan 2015 14:50:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2015/01/14/announcing-sql-parameterization-in-documentdb/</guid>
      <description><![CDATA[We are pleased to announce support for parameterized SQL queries in the Azure DocumentDB REST API...]]></description>
      <content:encoded><![CDATA[<p>We are pleased to announce support for parameterized SQL queries in the <a href="https://azure.microsoft.com/en-us/services/documentdb/" target="_blank">Azure DocumentDB </a>REST API and SDKs. Using this feature, you can now write parameterized SQL queries. Parameterized SQL provides robust handling and escaping of user input, preventing accidental exposure of data through &ldquo;SQL injection&rdquo; *.</p>
<p>Let's take a look at a sample using the .NET SDK; In addition to plain SQL strings and LINQ expressions, we've added a new SqlQuerySpec class that can be used to build parameterized queries. <br />Here's a sample that queries a "Books" collection with a single user supplied parameter for author name:</p>
<p>IQueryable&lt;Book&gt; queryable = client.CreateDocumentQuery&lt;Book&gt;(collectionSelfLink, new SqlQuerySpec { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QueryText = "SELECT * FROM books b WHERE (b.Author.Name = @name)", <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parameters = new SqlParameterCollection()&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new SqlParameter("@name", "Herman Melville") <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />});</p>
<p>A few interesting things to note here:</p>
<ul>
<li>SQL parameters in DocumentDB use the familiar @ notation borrowed from T-SQL</li>
<li>Parameter values can be any valid JSON (strings, numbers, Booleans, null, even arrays or nested JSON)</li>
<li>Since DocumentDB is schema-less, parameters are not validated against any type</li>
<li>We could just as easily supply additional parameters by adding additional SqlParameters to the SqlParameterCollection</li>
</ul>
<p>The DocumentDB REST API also natively supports parameterization. The .NET sample shown above translates to the following REST API call. To use parameterized queries, you need to specify the Content-Type Header as <em><strong>application/query+json</strong></em> and the query as JSON in the body, as shown below.</p>
<pre class="prettyprint">POST https://contosomarketing.documents.azure.com/dbs/XP0mAA==/colls/XP0mAJ3H-AA=/docs
HTTP/1.1 x-ms-documentdb-isquery: True 
x-ms-date: Mon, 18 Aug 2014 13:05:49 GMT 
authorization: type%3dmaster%26ver%3d1.0%26sig%3dkOU%2bBn2vkvIlHypfE8AA5fulpn8zKjLwdrxBqyg0YGQ%3d 
x-ms-version: 2014-08-21 
Accept: application/json 
Content-Type: application/query+json 
Host: contosomarketing.documents.azure.com 
Content-Length: 50 
{      
    "query": "SELECT * FROM books b WHERE (b.Author.Name = @name)",     
    "parameters": [          
        {"name": "@name", "value": "Herman Melville"}         
    ] 
}</pre>
<p>Queries can be issued against document collections, as well as system metadata collections like Databases, DocumentCollections, and Attachments using the approach shown above. To try this out, download the latest build of the DocumentDB SDK on any of the supported platforms (.NET, Java, Node.js, JavaScript, or Python).</p>
<blockquote>
<p><em><span style="font-size: small;">*DocumentDB is not susceptible to the most common kinds of injection attacks that lead to &ldquo;elevation of privileges&rdquo; because queries are strictly read-only operations. However, it might be possible for a user to gain access to data they shouldn&rsquo;t be accessing within the same collection by crafting malicious SQL queries. SQL parameterization support helps prevent these sort of attacks.</span></em></p>
</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Performance Tips for Azure DocumentDB - Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/performance-tips-for-azure-documentdb-part-1</link>
      <pubDate>Wed, 14 Jan 2015 14:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2015/01/14/performance-tips-for-azure-documentdb-part-1/</guid>
      <description><![CDATA[Performance Tips for Azure DocumentDB &ndash; Part 1
Azure DocumentDB allows you to optimize the...]]></description>
      <content:encoded><![CDATA[<p><strong>Performance Tips for Azure DocumentDB &ndash; Part 1</strong></p>
<p><a href="https://azure.com/docdb">Azure DocumentDB</a> allows you to optimize the performance of your database to best meet the needs of your application.&nbsp; We&rsquo;ve prepared a two part blog post series which will cover a number of areas that influence the performance of Azure DocumentDB.</p>
<p>In part 1, we look at the networking and SDK configuration options available in DocumentDB and their impact on performance. In part 2 we will cover indexing policy, throughput optimization and consistency levels.&nbsp; Like any performance tuning recommendation, not every one of these tips may be applicable for your use case, but you can use this information as a guide in order to assist you in making the right design choices for your applications.</p>
<p><strong>NETWORKING</strong></p>
<p><strong>Networking Tip #1 Connection Policy - Use direct connection mode for better performance</strong></p>
<p>First, let&rsquo;s take a look at Connection Policy. How a client connects to Azure DocumentDB has important implications on performance, especially in terms of observed client-side latency. There are two key configuration settings available for configuring client Connection Policy &ndash; the connection <em>mode</em> and the connection <em>protocol</em>.&nbsp; The two available modes are:</p>
<ol>
<li>Gateway Mode (default)</li>
<li>Direct Mode</li>
</ol>
<p>Since DocumentDB is a distributed storage system, DocumentDB resources like collections and documents are partitioned across numerous machines and each partition is replicated for high availability. The logical to physical address translation is kept in a routing table which is also internally available as a resource.</p>
<p>In Gateway Mode, the DocumentDB gateway machines perform this routing, thereby allowing client code to be simple and compact. A client application issues requests to the DocumentDB gateway machines, which translate the logical URI in the request to the physical address of the backend node, and forward the request appropriately.&nbsp; Conversely, in Direct Mode clients must maintain &ndash; and periodically refresh &ndash; a copy of this routing table, and then directly connect to the backend DocumentDB nodes.</p>
<p>Gateway Mode is supported on all SDK platforms and is the configured default.&nbsp; If your application runs within a corporate network with strict firewall restrictions, Gateway Mode is the best choice since it uses the standard HTTPS port and a single endpoint. The performance tradeoff, however, is that Gateway Mode involves an additional network hop every time data is read or written to DocumentDB.&nbsp;&nbsp; Because of this, Direct Mode offers better performance due to fewer network hops.</p>
<p><em>Direct Mode is currently supported only in the .NET SDK, but will be available in other platforms with subsequent SDK refreshes</em><em>.&nbsp; Read more about client connectivity options <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-interactions-with-resources/">here</a>.</em></p>
<p><strong>Networking Tip #2 Connection Policy - Use TCP protocol for better performance</strong></p>
<p>When leveraging Direct Mode, there are two protocol options available:</p>
<ol>
<li>TCP</li>
<li>HTTPS</li>
</ol>
<p>DocumentDB offers a simple and open RESTful programming model over HTTPS. Additionally, it offers an efficient TCP protocol which is also RESTful in its communication model and is available through the .NET client SDK. For best performance, use the TCP protocol when possible.</p>
<p>The Connectivity Mode is configured during the construction of the DocumentClient instance with the ConnectionPolicy parameter. If Direct Mode is used, the Protocol can also be set within the ConnectionPolicy parameter.</p>
<pre class="prettyprint">            var serviceEndpoint = new Uri("https://contoso.documents.net");
            var authKey = new "your authKey from Azure Mngt Portal";
            DocumentClient client = new DocumentClient(serviceEndpoint, authKey, 
            new ConnectionPolicy
            {
                ConnectionMode = ConnectionMode.Direct,
                ConnectionProtocol = Protocol.Tcp
            });</pre>
<p><em>Because TCP is only supported in Direct Mode, if Gateway Mode is used, then the HTTPS protocol is always used to communicate with the Gateway and the Protocol value in the ConnectionPolicy is ignored.</em></p>
<p><a href="https://acom.azurecomcdn.net/80C57D/blogmedia/blogmedia/2015/01/13/ConnectionPolicy.png"><img src="https://acom.azurecomcdn.net/80C57D/blogmedia/blogmedia/2015/01/13/ConnectionPolicy.png" alt="ConnectionPolicy" width="623" height="338" /></a> <br /><em>Connection policy illustrated</em></p>
<p><strong>Networking Tip #3: Call OpenAsync to avoid startup latency on first request</strong></p>
<p>By default, the first request will have a higher latency because it has to fetch the address routing table. In order to avoid this startup latency on the first request, you should call OpenAsync() once during initialization as follows.</p>
<pre class="prettyprint">await client.OpenAsync();</pre>
<p><strong>Networking TIP #4: Collocate clients in same Azure region for performance</strong></p>
<p>It is possible to experience high network latency between making a request to DocumentDB and receiving the response. This latency could likely vary from request to request depending on the route taken by the request from the client to the Azure datacenter boundary. The lowest possible latency will be achieved by ensuring the calling application is located within the same Azure region as the provisioned DocumentDB endpoint.</p>
<p><a href="https://acom.azurecomcdn.net/80C57D/blogmedia/blogmedia/2015/01/13/DeploymentConsiderations.png"><img src="https://acom.azurecomcdn.net/80C57D/blogmedia/blogmedia/2015/01/13/DeploymentConsiderations.png" alt="DeploymentConsiderations" width="517" height="279" /></a> <br /><em> <br />Deployment considerations illustrated</em></p>
<p><strong>SDK USAGE</strong></p>
<p><strong>SDK Usage Tip #1: Use a singleton DocumentDB client for the lifetime of your application</strong></p>
<p>Note that each DocumentClient instance is thread-safe and performs efficient connection management and address caching when operating in Direct Mode. To allow efficient connection management and better performance by DocumentClient, it is recommended to use a single instance of DocumentClient per AppDomain for the lifetime of the application.</p>
<p><strong>SDK Usage Tip #2: Cache document and collection SelfLinks for lower read latency</strong></p>
<p>In Azure DocumentDB, each document has a system-generated selfLink. These selfLinks are guaranteed to be unique and immutable for the lifetime of the document. Reading a single document using a selfLink is the most efficient way to get a single document. Due to the immutability of the selfLink, you should cache selfLinks whenever possible for best read performance.</p>
<pre class="prettyprint">Document document = await client.ReadDocumentAsync("/dbs/1234/colls/1234354/docs/2332435465");</pre>
<p>Having said that, it may not be always possible for the application to work with a document&rsquo;s selfLink for read scenarios; in this case, the next most efficient way to retrieve a document is to query by the document&rsquo;s user provided Id property.&nbsp; For example:</p>
<pre class="prettyprint">            IDocumentQuery&lt;Document&gt; query = (
                    from doc in client.CreateDocumentQuery(documentsLink)
                    where doc.Id == "myId"
                    select doc).AsDocumentQuery();

            Document myDocument = null;
            while (query.HasMoreResults)
            {
                FeedResponse&lt;Document&gt; res = await query.ExecuteNextAsync&lt;Document&gt;();
                if (res.Any())
                {
                    myDocument = res.Single();
                    break;
                }
            }

            return myDocument;</pre>
<p><strong>SDK Usage Tip #3: Tune page size for queries/read feeds for better performance</strong></p>
<p>When performing a bulk read of documents using read feed functionality (i.e. ReadDocumentFeedAsync) or when issuing a DocumentDB SQL query, the results are returned in a segmented fashion if the result set is too large. By default, results are returned in chunks of 100 items or 1 MB, whichever limit is hit first.</p>
<p>In order to reduce the number of network round trips required to retrieve all applicable results, you can increase the page size using x-ms-max-item-count request header to up to 1000. In cases where you need to display only a few results, e.g., if your user interface or application API returns only ten results a time, you can also decrease the page size to 10 in order to reduce the throughput consumed for reads and queries.</p>
<p>You may also set the page size using the available DocumentDB SDKs.&nbsp; For example:</p>
<pre class="prettyprint">            IQueryable&lt;dynamic&gt; authorResults = client.CreateDocumentQuery(documentsLink, 
                "SELECT p.Author FROM Pages p WHERE p.Title = 'About Seattle'", 
                new FeedOptions { MaxItemCount = 1000 });</pre>
<p><strong>WRAPPING UP</strong></p>
<p>We hope you found one or more of these tips both useful and applicable to your usage of DocumentDB.&nbsp; In part 2 of this blog series we will continue the discussion and cover indexing policies, throughput optimization and consistency levels.&nbsp; In addition, we&rsquo;d love to hear from you about the DocumentDB features and experiences you would find most valuable.&nbsp;</p>
<p>Please submit your suggestions on the Microsoft Azure DocumentDB <a href="https://feedback.azure.com/forums/263030-documentdb?filter=top&amp;page=1">feedback forum</a>.&nbsp;</p>
<p>If you haven&rsquo;t tried DocumentDB yet, then get started <a href="https://azure.microsoft.com/en-us/services/documentdb/">here</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Introducing the Azure DocumentDB Java SDK</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/introducing-the-azure-documentdb-java-sdk</link>
      <pubDate>Thu, 11 Dec 2014 11:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Andrew Liu (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2014/12/11/introducing-the-azure-documentdb-java-sdk/</guid>
      <description><![CDATA[We are pleased to announce the release of the Azure DocumentDB Java SDK! The Java SDK allows you to...]]></description>
      <content:encoded><![CDATA[<p>We are pleased to announce the release of the <a href="https://azure.microsoft.com/en-us/services/documentdb/">Azure DocumentDB</a> Java SDK! <br />The Java SDK allows you to easily create, read, update, and delete various DocumentDB resources as well as manage advanced configuration settings.</p>
<p>As usual, you can find all of the source code available via <a href="https://github.com/Azure/azure-documentdb-java">github</a>:</p>
<pre class="prettyprint">git clone git://github.com/Azure/azure-documentdb-java.git</pre>
<p>As a fully open-sourced SDK, we love and welcome your contributions. Please follow the instructions provided in the <a href="https://azure.github.io/guidelines.html">Azure Projects Contributions Guidelines</a>.</p>
<p>You can also get the latest binaries, ready to use within your project, via Maven:</p>
<pre class="prettyprint">&lt;dependency&gt; 
	&lt;groupId&gt;com.microsoft.azure&lt;/groupId&gt; 
	&lt;artifactId&gt;azure-documentdb&lt;/artifactId&gt; 
	&lt;version&gt;0.9.0&lt;/version&gt; 
&lt;/dependency&gt;</pre>
<p><span>For more information on DocumentDB, Microsoft&rsquo;s fully managed NoSQL document database service in the cloud, go&nbsp;</span><a href="https://azure.microsoft.com/en-us/services/documentdb/">here</a><span>.</span></p>
<p>We have published a&nbsp;<a title="Java SDK Tutorial" href="https://go.microsoft.com/fwlink/?LinkID=522425&amp;clcid=0x409">quick tutorial</a> on how to create a Java web application on top of DocumentDB to help you get started.</p>
<p>If you need any help, please reach out to us on the <a href="https://social.msdn.microsoft.com/forums/azure/en-US/home?forum=AzureDocumentDB">Azure DocumentDB Developer Forums on MSDN</a> or the <a href="https://stackoverflow.com/questions/tagged/azure-documentdb">developer forums on stack overflow</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Scaling a Multi-Tenant Application with Azure DocumentDB</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/scaling-a-multi-tenant-application-with-azure-documentdb</link>
      <pubDate>Wed, 03 Dec 2014 09:45:00 GMT</pubDate>
      <dc:creator><![CDATA[Andrew Liu (MSFT)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2014/12/03/scaling-a-multi-tenant-application-with-azure-documentdb/</guid>
      <description><![CDATA[Best Practices for Tenant Placement and Load Balancing
Introduction
A question that we are...]]></description>
      <content:encoded><![CDATA[<h5>Best Practices for Tenant Placement and Load Balancing</h5>
<h2>Introduction</h2>
<p align="justify">A question that we are frequently asked is &ldquo;How do I design a multi-tenant application on top of <a href="https://azure.microsoft.com/en-us/services/documentdb/">Azure DocumentDB</a>?&rdquo; There are many answers to this question, and the best answer depends on your application&rsquo;s particular scenario.</p>
<p align="justify">At a high-level, depending on the scale of your tenants you could choose to partition by database or collection. In cases where tenant data is smaller and tenancy numbers are higher &ndash; we suggest that you store data for multiple tenants in the same collection to reduce the overall resources necessary for your application. You can identify your tenant by a property in your document and issue filter queries to retrieve tenant-specific data. You can also use DocumentDB&rsquo;s <a href="https://msdn.microsoft.com/en-us/library/dn783368.aspx">users and permissions</a> to isolate tenant data and restrict access at a resource-level via authorization keys.</p>
<p align="justify">In cases where tenants are larger, need dedicated resources, or require further isolation - you can allocate dedicated collections or databases for tenants. In either case, DocumentDB will handle a significant portion of the operational burden for you as you scale-out your application&rsquo;s data store.</p>
<p align="justify">In this article, we will discuss the concepts and strategies to help guide you towards a great design to fit your application&rsquo;s requirements.</p>
<h2>What is a Collection?</h2>
<p align="justify">Before we dive deeper on partitioning data, it is important to understand what a collection is and what it isn&rsquo;t.</p>
<p align="justify">As you may already know, a collection is a container for your JSON documents. Collections are also DocumentDB&rsquo;s unit of partition and boundary for the execution of queries and transactions. Each collection provides a reserved amount of throughput. You can scale out your application, in terms of both storage and throughput, by adding more collections, and distributing your documents across them.</p>
<p align="justify">It is absolutely imperative to understand that collections are <em>not</em> tables. Collections do <em>not</em> enforce schema; in other words, you can store different types of documents with different schemas in the same collection. You can track different types of entities simply by adding a &ldquo;type&rdquo; attribute to your document.</p>
<p align="justify">Unlike some other document-databases, there is nothing wrong with having a lot of collections to achieve greater scale and performance. You may, however, want to re-use collections from a cost-savings perspective.</p>
<h2>Sharding with DocumentDB</h2>
<p align="justify">You can achieve near-infinite scale (in terms of storage and throughput) for your DocumentDB application by horizontally partitioning your data &ndash; a concept commonly referred to as sharding.</p>
<p align="justify">Sharding is a standard application pattern for achieving high scalability for large web applications. For applications that require the benefits of transactions, an application will need to partition its data carefully based on a key with each partition small enough to fit into a transaction domain (i.e. a collection). Sharded applications must be aware that data is spread across a number of partitions or transaction domains and need logic to select a partition and interact with it based on a shard-key.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/6406.shard-example_7BF5650D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/6406.shard_2D00_example_5F00_7BF5650D.png"><img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border-width: 0px;" title="shard-example" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/8233.shard-example_thumb_5E831401.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/8233.shard_2D00_example_5F00_thumb_5F00_5E831401.png" alt="shard-example" width="480" height="478" border="0" /></a></p>
<p align="center"><em>A DocumentDB Application sharded across databases and collections.</em></p>
<h2>Partitioning Scopes</h2>
<p align="justify">The decision of whether to shard across multiple transactional domains depends on the scale of your application &ndash; as sharding generally involves additional data management logic in your application.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/6180.resourcemodel_6C5559FC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/6180.resourcemodel_5F00_6C5559FC.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="resourcemodel" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4846.resourcemodel_thumb_3748CACC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4846.resourcemodel_5F00_thumb_5F00_3748CACC.png" alt="resourcemodel" width="480" height="382" border="0" /></a></p>
<p align="center"><em>Hierarchical Resource Model under a Database Account</em></p>
<p align="justify">Let&rsquo;s take a closer examination at the DocumentDB&rsquo;s resource model and the various scopes that you could potentially partition your data across:</p>
<p align="justify">Placing all tenants in a single collection - This is generally a good starting point for most applications &ndash; e.g. whenever the total resource consumption across all of your tenants is well within the storage and throughput limitations of a single collection.</p>
<p align="justify">Security can be enforced at the application level simply by adding a tenant property inside your document and enforcing a tenant filter on all queries (e.g. SELECT * FROM collection c WHERE c.userId = &ldquo;Andrew&rdquo;). Security can be enforced at the DocumentDB level as well by creating a user for each tenant, assigning permissions to tenant data, and querying tenant data via the user&rsquo;s authorization key.</p>
<p align="justify">Major benefits of storing tenant data within a single collection include reducing complexity, ensuring transactional support across application data, and minimizing financial cost of storage.</p>
<p align="justify">Placing tenants across multiple collections &ndash; In cases where your application needs more storage or throughput capacity than a single collection can handle, you can partition data across multiple collections. Fortunately, there is no need to set a limit on the size of your database and the number of collections. DocumentDB allows you to dynamically add collections and capacity as your application grows. You will, however, need to decide how the application will partition tenant data and route requests, which we&rsquo;ll discuss in just a moment.</p>
<p align="justify">In addition to increased resource capacity, an advantage of partitioning data across multiple collections is the ability to allocate more resources for larger tenants over smaller tenants by placing them in less dense collections (e.g. you can place a tenant, who needs dedicated throughput, on to their own collection).</p>
<p align="justify">Placing tenants across multiple databases &ndash; For the most part, placing tenants across databases works fairly similar to placing tenants across collections. As shown in the resource model diagram above, the major distinction between DocumentDB collections and databases is that users and permissions are scoped at a database-level. In other words, each database has its own set of users and permissions &ndash; which you can use to isolate specific collections and documents.</p>
<p align="justify">Partitioning tenants by database may simplify user and permission management in scenarios where tenants require an extremely large set of users and permissions. When tenants are partitioned by database and the tenant leaves the application &ndash; the tenant&rsquo;s data along with their users and permissions can all be discarded together simply by deleting the database.</p>
<p align="justify">Placing tenants across multiple database accounts &ndash; Likewise, placing tenants across database accounts works fairly similar to placing tenants across databases. The major distinction between database accounts and databases is that the master/secondary keys, DNS endpoints, and billing are scoped at a database account level.</p>
<p align="justify">Partitioning tenants by database account allows applications to maintain isolation between tenants in scenarios where tenants require access to their own database account keys (e.g. tenants require the ability to create, delete, and manage their own set of collections and users).</p>
<h2>Common Sharding Patterns</h2>
<p align="justify">If you&rsquo;re partitioning data across multiple transactional domains, your application will need some sort of heuristic to partition its data and route requests to the correct partition. Some common heuristics for partitioning data include:</p>
<h3>Range Partitioning</h3>
<p align="justify">Partitions are assigned based on whether the partitioning key is inside a certain range. An example could be to partition data by timestamp or geography (e.g. zip code is between 30000 and 39999).</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/7607.partition-range_6FBB9CEA.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/7607.partition_2D00_range_5F00_6FBB9CEA.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="partition-range" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/8267.partition-range_thumb_2B7B359E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/8267.partition_2D00_range_5F00_thumb_5F00_2B7B359E.png" alt="partition-range" width="500" height="117" border="0" /></a></p>
<p align="center"><em>Range-Partitioning by Month</em></p>
<h3>Lookup Partitioning</h3>
<p>Partitions are assigned based on a lookup directory of discrete values that map to a partition. This is generally implemented by creating a lookup map that keeps track of which data is stored on which partition. You can cache look-up results to avoid making multiple round-trips. An example could be to partition data by user (e.g. partition G contains Harry, Ron, and Hermione and partition S contains Draco, Vincent, and Gregory) or country (e.g. partition Scandinavia contains Norway, Denmark, and Sweden)</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/6866.partition-dictionary_2CDF5870.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/6866.partition_2D00_dictionary_5F00_2CDF5870.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="partition-dictionary" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/7446.partition-dictionary_thumb_689EF123.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/7446.partition_2D00_dictionary_5F00_thumb_5F00_689EF123.png" alt="partition-dictionary" width="524" height="199" border="0" /></a></p>
<p align="center"><em>Lookup Partitioning</em></p>
<h4>Hash Partitioning</h4>
<p>Partitions are based on the value of a hash function &ndash; allowing you to evenly distribute across n number of partitions. An example could be to partition data by the hash code % 3 of the tenant to evenly distribute tenants across 3 partitions.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4745.partition-hash_339261F3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4745.partition_2D00_hash_5F00_339261F3.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="partition-hash" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/1682.partition-hash_thumb_56562A61.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/1682.partition_2D00_hash_5F00_thumb_5F00_56562A61.png" alt="partition-hash" width="500" height="146" border="0" /></a></p>
<p align="center"><em>Hash Partitioning</em></p>
<p align="justify">So which partitioning strategy is right for you? Range partitioning is generally useful in the context of dates, as it gives you an easy and natural mechanism for ageing out partitions. Lookup partitioning, on the other hand, allows you to group and organize unordered and unrelated sets of data in a natural way (e.g. group tenants by organization or states by geographic region). Hash partitioning is incredibly useful for load balancing when it is difficult to predict and manually balance the amount of data for particular groups or when range partitioning would cause the data to be undesirably clustered.</p>
<p align="justify">You don&rsquo;t have to choose just one partitioning strategy either! A composite of these strategies can also be useful depending on the scenario &ndash; for example, a composite range-lookup partitioning may provide you both the manageability of range partitioning as well as the explicit control of lookup partitioning.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/3833.partition-composite_363B1DA4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/3833.partition_2D00_composite_5F00_363B1DA4.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="partition-composite" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/3755.partition-composite_thumb_55E9F76C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/3755.partition_2D00_composite_5F00_thumb_5F00_55E9F76C.png" alt="partition-composite" width="500" height="148" border="0" /></a></p>
<p align="center"><em>Composite Range-Lookup Partitioning</em></p>
<h3>Fan-Out Operations</h3>
<p>A common method for operating on data across multiple transactional domains is to issue a fan-out query, in which the application queries each partition in parallel and then consolidate the results.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4834.fanout_63BC3D67.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4834.fanout_5F00_63BC3D67.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="fanout" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4857.fanout_thumb_0A8A53A8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4857.fanout_5F00_thumb_5F00_0A8A53A8.png" alt="fanout" width="500" height="283" border="0" /></a></p>
<p align="center"><em>Fan-Out Query</em></p>
<p align="justify">A primary architecture decision is when the fan-out occurs. Let&rsquo;s use a news-feed aggregation timeline as an example; some common strategies for fan-out include:<em></em></p>
<p align="justify">Fan-Out on Write<em> &ndash; </em>The idea here is to avoid computation on reads and to do most of the processing on writes, making read time access extremely fast and easy. This may be a good decision if the timeline resembles something like Twitter &ndash; a roughly permanent, append-only, per-user aggregation of a set of source feeds. When an incoming event is recorded, it is stored in the source feed and then a record containing a copy is created for each timeline that it must be visible in. <em></em></p>
<p align="justify">Fan-Out on Read &ndash; This may be a good decision if the timeline resembles something like Facebook &ndash; in which the feed is temporal and needs to support dynamic features (such as real-time privacy checks and tailoring of content). When an event is recorded, it is only stored in the source feed. Every time a user requests their individual timeline, the system fan-out reads to all of the source feed the user has visibility into and aggregates the feeds together.<em></em></p>
<h2>Managing Storage and Throughput</h2>
<p align="justify">When a partition begins to fill up and run out of resources, it is time to spill-over or re-distribute data to another partition. This may occur when an outlying tenant is consuming more storage and/or throughput than expected, or the application is simply outgrowing the existing partitions. You will want to monitor and pick an appropriate threshold (e.g. 80% of storage consumed), based on the rate that which resources are consumed, to act upon to prevent the possibility of application failure.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/3362.spillover_185C99A3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/3362.spillover_5F00_185C99A3.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="spillover" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/7870.spillover_thumb_78418CE5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/7870.spillover_5F00_thumb_5F00_78418CE5.png" alt="spillover" width="300" height="135" border="0" /></a></p>
<p align="center"><em>Maintain enough headroom before having to spill-over/re-distribute data to avoid service-interruption.</em></p>
<p align="justify">One strategy to overcome storage-constraints may be to spill over incoming data in to a new collection. For example, spill-over may work well if your collections store highly temporal data and are partitioned by month or date. In this context, you could even consider pruning or archiving older collections as the age and become stale. It&rsquo;s important to keep in mind that collections are the boundary for transactions and queries; you may have to fan-out your reads or writes if dealing with data across collections.</p>
<p align="justify">Another strategy to overcome storage and/or throughput constraints is to re-distribute your tenant data. For example, you could move an outlying tenant that consumes a lot more throughput than others to another collection. You may want to fan-out reads and/or writes during the migration process to avoid service interruption for the particular tenant.</p>
<h2>Conclusion</h2>
<p align="justify">DocumentDB has proven to scale for various multi-tenant scenarios here within Microsoft, including MSN which stores user data for Health &amp; Fitness experiences (web and mobile) in a sharded database account. Check out the <a href="https://azure.microsoft.com/blog/2014/10/09/azure-documentdb-profile-of-msn-health-and-fitness-2/">blog post</a> on this use case!</p>
<p align="justify">For most things, the design for your application will depend heavily on its scenarios and data access patterns. Hopefully this article will serve as a great starting point to guide you in the right direction.</p>
<p align="justify">To learn how to <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-create-account/">get started</a> with DocumentDB or for more information, please check out <a href="https://azure.microsoft.com/en-us/documentation/services/documentdb/">our website</a>.</p>
<p align="justify">For more information on developing multi-tenant applications on Microsoft Azure in general, check out this great <a href="https://msdn.microsoft.com/en-us/library/ff966499.aspx">MSDN article</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Working with Dates in Azure DocumentDB</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/working-with-dates-in-azure-documentdb</link>
      <pubDate>Mon, 17 Nov 2014 17:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Ryan CrawCour [MSFT]]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2014/11/17/working-with-dates-in-azure-documentdb/</guid>
      <description><![CDATA[JSON (www.json.org) is a lightweight data-interchange format that is easy for humans to read and...]]></description>
      <content:encoded><![CDATA[<p>JSON (<a href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/www.json.org" target="_blank">www.json.org</a>) is a lightweight data-interchange format that is easy for humans to read and write yet also easy for machines to parse and generate. JSON is at the heart of <a href="https://azure.microsoft.com/en-us/services/documentdb/" target="_blank">DocumentDB</a>. We transmit JSON over the wire, we store JSON as JSON, and we index the JSON tree allowing queries on the full JSON document. It is not something we bolt on to the product, it is core to the service. <br />It should therefore come as no surprise that DocumentDB natively supports the same data types as JSON; String, Number, Boolean, Array, Object and Null.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/5417.1_25BF8BF6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/5417.1_5F00_25BF8BF6.jpg"><img style="float: none; padding-top: 0px; padding-left: 0px; padding-right: 0px; border-width: 0px;" title="1" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/2768.1_thumb_1376C534.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/2768.1_5F00_thumb_5F00_1376C534.jpg" alt="1" width="480" height="168" border="0" /></a></p>
<p>A .NET developer might notice the omission of certain types they are used to. Most notable is probably the .NET DateTime type. So, how do we store, retrieve, and query using DateTime if the database doesn&rsquo;t support these types natively?</p>
<p>Keep reading as that is the purpose of this post &hellip;</p>
<p>For the purposes of this post let us assume we&rsquo;re working with the following sample POCO objects.</p>
<pre class="prettyprint">    public class Order
    {
        public string OrderNumber { get; set; }
        public DateTime OrderDate { get; set; }
        public DateTime ShipDate { get; set; }
        public double Total { get; set; }
    }</pre>
<p>This is a simple demonstration of how an Order could be represented in .NET. <br />The order has two DateTime properties, OrderDate and ShipDate. For the purposes of this post we will be focusing primarily on these two properties. <br />The default format used by the DocumentDB SDK for handling DateTime objects is to convert them in to the ISO 8601 string format. Therefore, if we do nothing but pass our Order object to DocumentDB, as shown in the code snippet below,</p>
<pre class="prettyprint">var doc1 = client.CreateDocumentAsync(colLink, new Order { 
      OrderNumber = "09152014101",
      OrderDate = DateTime.UtcNow.AddDays(-30),
      ShipDate = DateTime.UtcNow.AddDays(-14), 
      Total = 113.39
});</pre>
<p><br />The two .NET DateTime properties would be stored as a string similar to;</p>
<pre class="prettyprint">{
    "OrderDate": "2014-09-15T23:14:25.7251173Z",
    "ShipDate": "2014-09-30T23:14:25.7251173Z"
}</pre>
<p>That string looks nice and readable like that, so why is this a problem?</p>
<p>DocumentDB has support for range based indexes on numeric fields allowing you to do range queries, (e.g. where field &gt; 10 and field &lt; 20). To avoid doing costly scans when doing range queries (records older than yesterday, or orders placed last week, or orders shipped today) on dates we need to convert the string representation of a Date to a number, so that we can use range indexes on these fields.</p>
<p>DocumentDB and JSON are neutral to how they represent DateTimes and you can use this neutrality to powerful effect to best suit your application&rsquo;s needs.</p>
<p>This post introduces two methods of dealing with DateTime properties efficiently, but there are many more implementations that would treat Dates and Times efficiently.</p>
<p>&nbsp;</p>
<p>For the rest of the post we will be treating DateTimes as epoch values, or the number of seconds since a particular date. We are using 1 January 1970 00:00 in this post, you can use a different starting point if you like depending on your data. I.e. if you are doing orders and your system only needs to deal with orders from today, then pick today as your starting point. Our fictitious system has lots of historical orders, so we need to go back in time a little.</p>
<p>Here is a simple .NET extension method for DateTime that will do this conversion for us;</p>
<pre class="prettyprint">public static class Extensions
{
    public static int ToEpoch(this DateTime date)
    {
        if (date == null) return int.MinValue;
        DateTime epoch = new DateTime(1970, 1, 1);
        TimeSpan epochTimeSpan = date - epoch;
        return (int)epochTimeSpan.TotalSeconds;
    }
}</pre>
<p>Now how do you use this in your application?</p>
<p>Well there are two ways to proceed, and you can choose the way that best suits the needs of your application.</p>
<p>The first way is store a number field that represents the DateTime <strong>instead</strong> of the DateTime itself.</p>
<p>The easiest way to do this is to implement a custom serializer &amp; deserializer for dealing with JSON. I&rsquo;m going to show doing this with JSON.NET by implementing a customer JsonConverter that changes the default behavior of a DateTime property.</p>
<p>To do this we define a class that extends the JsonConverter abstract class and overrides the ReadJson and WriteJson methods.</p>
<pre class="prettyprint">public class EpochDateTimeConverter : JsonConverter
{
    ...
}</pre>
<p><br />Below is the WriteJson implementation that takes&nbsp; in&nbsp; a .NET DateTime and outputs a number using the same ToEpoch() extension method we created above.</p>
<pre class="prettyprint">public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    int seconds;
    if (value is DateTime)
    {
        DateTime dt = (DateTime)value;
        if (!dt.Equals(DateTime.MinValue))
            seconds = dt.ToEpoch();
        else
            seconds = int.MinValue;
    }
    else
    {
        throw new Exception("Expected date object value.");
    }

    writer.WriteValue(seconds);
}</pre>
<p><br />We also have the reverse, the ReadJson method, which will be used during serialization from JSON back in to .NET. This method takes in a number representing the number of seconds since Jan 1 1970 UTC and returns the .NET DateTime equivalent.</p>
<pre class="prettyprint">public override object ReadJson(JsonReader reader, Type type, object value, JsonSerializer serializer)
{
    if (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Null) 
        return null;

    if (reader.TokenType != JsonToken.Integer)
    {
        throw new Exception(
            String.Format("Unexpected token parsing date. Expected Integer, got {0}.",
            reader.TokenType));
    }

    int seconds = (int)reader.Value;
    return new DateTime(1970, 1, 1).AddSeconds(seconds);
}</pre>
<p><br />To use this in an application we need to decorate our DateTime properties with the JsonConverter attribute. Now, when these properties are serialized / deserialized Json.NET knows not to work with its default but to use our custom code instead.</p>
<pre class="prettyprint">    public class Order
    {
        public string OrderNumber { get; set; }
</pre>
<pre class="prettyprint">        [JsonConverter(typeof(EpochDateTimeConverter))]
        public DateTime OrderDate { get; set; }

        [JsonConverter(typeof(EpochDateTimeConverter))]
        public DateTime ShipDate { get; set; }

        public double Total { get; set; }
    }</pre>
<p><br />The result after serialization is now a number in JSON and a number being stored in DocumentDB.</p>
<pre class="prettyprint">{
    "OrderDate": 1408318702,
    "ShipDate": 1408318702 
}</pre>
<p>To do an efficient range queries on a numeric field in DocumentDB we have to define a Range Index on the path containing our numeric field, when we create the DocumentCollection.</p>
<p>The example below shows creating a DocumentCollection with a custom IndexPolicy. We use a Numeric Precision of 7 bytes for this range index because we are dealing with numbers in the billions. For a smaller range of numbers it would be sufficient to use smaller precision levels.</p>
<pre class="prettyprint">var collection = new DocumentCollection
{
    Id = id
};

//set the default IncludePath to set all properties in the document to have a Hash index
collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Hash,
    Path = "/",
});

//now define two additional paths in Order that we know we want to do Range based queries on
collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Range,
    Path = "/\"OrderDate\"/?",
    NumericPrecision = 7
});

collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Range,
    Path = "/\"ShipDate\"/?",
    NumericPrecision = 7
});

collection = client.CreateDocumentCollectionAsync(dbLink, collection).Result;</pre>
<p><br />Once this is in place, doing a query on a DateTime property is as easy as;</p>
<pre class="prettyprint">//convert "7 days ago" to epoch number using our ToEpoch extension method for DateTime
int epocDateTime DateTime.UtcNow.AddDays(-7).ToEpoch();

//build up the query string
string sql = string.Format("SELECT * FROM Collection c WHERE c.OrderDate &gt; {0}", <br />    epocDateTime);

//execute the query and get the results in a List
var orders = client.CreateDocumentQuery&lt;Order&gt;(col.SelfLink, sql).ToList();</pre>
<p>That&rsquo;s one approach, and it works very efficiently. The downside however is that you lose the human readable date string in your database. Should another application connect to our database the custom deserializer won&rsquo;t necessarily be run and the value returned is now difficult to deal with because not many humans can do an epoch conversion in their heads (I certainly can&rsquo;t).</p>
<p>The second way to implement this is to preserve the readable DateTime field but add an additional field to your document which stores the numeric representation of the DateTime in addition to the string representation.</p>
<p>To do this, we can create a new custom type that looks like this;</p>
<pre class="prettyprint">public class DateEpoch
{
   public DateTime Date { get; set; }
   public int Epoch
   {
       get
       {
           return (this.Date.Equals(null) || this.Date.Equals(DateTime.MinValue))
               ? int.MinValue
               : this.Date.ToEpoch();
        }
    }
}</pre>
<p><br />Now change the two DateTime properties of the Order object to this new type like this;</p>
<pre class="prettyprint">public class Order
{
    public string OrderNumber { get; set; }
    public DateEpoch OrderDate { get; set; }
    public DateEpoch ShipDate { get; set; }
    public double Total { get; set; }
}</pre>
<p><br />With this in place, when you now pass your object to DocumentDB you will end up with JSON that looks something like this;</p>
<pre class="prettyprint">{
    "OrderDate": {
        "Date": "2014-09-15T23: 14: 25.7251173Z",
        "Epoch": 1408318702
    },
    "ShipDate": {
        "Date": "2014-09-30T23: 14: 25.7251173Z",
        "Epoch": 1408318702
    }
}</pre>
<p><br />As you did with the first technique you have to define a custom IndexPolicy on your DocumentCollection except this time we add the range path on the Epoch value only. You could exclude the date string path from the index if you like but keeping the default hash index still allows for equality operations if you want to do that.</p>
<pre class="prettyprint">var collection = new DocumentCollection
{
    Id = id
};

//set the default IncludePath to set all properties in the document to have a Hash index
collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Hash,
    Path = "/",
});

//now define two additional paths in Order2 that we know we want to do Range based queries on
collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Range,
    Path = "/\"OrderDate\"/\"Epoch\"/?",
    NumericPrecision = 7
});

collection.IndexingPolicy.IncludedPaths.Add(new IndexingPath
{
    IndexType = IndexType.Range,
    Path = "/\"ShipDate\"/\"Epoch\"/?",
    NumericPrecision = 7
});

//could also exclude the Date portion of the dates in Order2 as we're never going to 
//index on these, but will leave these there because they're still indexed with a hash 
//so you could do equality operations on them.

collection = client.CreateDocumentCollectionAsync(dbLink, collection).Result;</pre>
<p><br />Now to query with this approach you could execute the following LINQ query, I chose to demonstrate LINQ here and not SQL as in the previous example, because this is another advantage of this approach.</p>
<pre class="prettyprint">var orders = from o in client.CreateDocumentQuery&lt;Order2&gt;(col.SelfLink)
    where o.OrderDate.Epoch &gt;= DateTime.Now.AddDays(-7).ToEpoch()
    select o;</pre>
<p><br />Or, you can choose the following LINQ Lambda syntax if you favor that;</p>
<pre class="prettyprint">var orders2 = client.CreateDocumentQuery&lt;Order2&gt;(col.SelfLink)
    .Where(o =&gt; o.OrderDate.Epoch &gt;= DateTime.UtcNow.AddDays(-7).ToEpoch())
    .ToList();</pre>
<p><br />And of course the SQL syntax we used earlier would also be valid and give the same result and is what you would use when LINQ was not available to you;</p>
<pre class="prettyprint">string sql = String.Format("SELECT * FROM c WHERE c.OrderDate.Epoch &gt;= {0}", 
                 DateTime.UtcNow.AddDays(-7).ToEpoch());</pre>
<p>This second approach has two main advantages over the first. Firstly it does not rely on a custom serialization technique for specific tool like JSON.NET so it can be used with other JSON serializers or with other languages beside just .NET. This technique would work equally well in say Node.JS or in Python. Secondly because we keep the human readable DateTime value as a string if another application queries your data, humans will still have a readable version of the date to work with.</p>
<p>This approach requires more storage and results in slightly larger documents as a result, but if you are not sensitive about the storage costs or the size of the document being too big then I favor this approach over the first for the benefits listed above.</p>
<p>And that&rsquo;s it, DateTime properties in DocumentDB. Done</p>
<p>If you would like the sample code for this blog post you can download it from <a href="https://ryancrawcour.blob.core.windows.net/samples/DateTime%20and%20DocumentDB.zip" target="_blank">here</a></p>
<p>To get started with Azure <a href="https://azure.microsoft.com/en-us/services/documentdb/" target="_blank">DocumentDB</a> head over to the service documentation page on azure.com&nbsp; =&gt; <a title="https://azure.microsoft.com/en-us/documentation/services/documentdb/" href="https://azure.microsoft.com/en-us/documentation/services/documentdb/">https://azure.microsoft.com/en-us/documentation/services/documentdb/</a> where you can find everything you need to get up &amp; running.</p>
<!--wp code prettify-->
<script type="text/javascript">// <![CDATA[
	function $(id) {return !id ? null : document.getElementById(id);}

	loadPrettifyCss = function () {
		if(!$('prettify_css')) {
			css = document.createElement('link');
			css.id = 'prettify_css';
			css.type = 'text/css';
			css.rel = 'stylesheet';
			css.href = 'https://azure.microsoft.com/blog/wp-content/plugins/wp-code-prettify/css/azure-code.css';
			var headNode = document.getElementsByTagName("head")[0];
			headNode.appendChild(css);
		} else {
			$('prettify_css').href = 'https://azure.microsoft.com/blog/wp-content/plugins/wp-code-prettify/css/azure-code.css';
		}

		if(!$('prettify_custom')) {
			css = document.createElement('style');
			css.id = 'prettify_custom';
			css.type = 'text/css';
			css.rel = 'stylesheet';
			css.innerHTML = 'pre.prettyprint { margin: 5px; padding: 10px; overflow: auto; background-color: #f8f8f8; font-family:Consolas, Monaco, Lucida Console, monospace; font-size:12px; line-height: 1.2em;}';
			var headNode = document.getElementsByTagName("head")[0];
			headNode.appendChild(css);
		} else {
			$('prettify_css').innerHTML = 'pre.prettyprint { margin: 5px; padding: 10px; overflow: auto; background-color: #f8f8f8; font-family:Consolas, Monaco, Lucida Console, monospace; font-size:12px; line-height: 1.2em;}';
		}
	}
// ]]]]><![CDATA[></script>
<script type="text/javascript">// <![CDATA[
		loadPrettifyCss();
// ]]]]><![CDATA[></script>
<script type="text/javascript" src="https://azure.microsoft.com/blog/wp-content/plugins/wp-code-prettify/js/prettify.js"></script>
<script type="text/javascript">// <![CDATA[
		window.onload = function(){ prettyPrint();}
// ]]]]><![CDATA[></script>
<!--//wp code prettify-->]]></content:encoded>
    </item>
    <item>
      <title>Bulk Add Documents and Query Syntax Highlighting</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/bulk-add-documents-and-query-syntax-highlighting</link>
      <pubDate>Wed, 12 Nov 2014 15:14:00 GMT</pubDate>
      <dc:creator><![CDATA[DocumentDB Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2014/11/12/bulk-add-documents-and-query-syntax-highlighting/</guid>
      <description><![CDATA[We&rsquo;ve released a couple of great improvements to further enhance the management experience for...]]></description>
      <content:encoded><![CDATA[<p>We&rsquo;ve released a couple of great improvements to further enhance the management experience for DocumentDB, the fully managed NoSQL document database service on Azure. We just released the following capabilities in the new Azure portal at <a href="https://portal.azure.com">https://portal.azure.com</a>:</p>
<ul>
<li>Bulk add Documents &ndash; Upload multiple existing JSON documents via Document Explorer</li>
<li>Query syntax highlighting &ndash; Keyword and value highlighting in Query Explorer</li>
<li>Improved query experience &ndash; Edit and re-execute queries without closing the results blade</li>
</ul>
<p>Keep reading for additional information on each of these new features or get started <a href="https://azure.microsoft.com/en-us/services/documentdb/">now</a> with <a>DocumentDB</a></p>
<p><span>Add Documents</span></p>
<p>Document Explorer allows you to easily create, edit, and delete JSON documents stored in DocumentDB and is available from any of the DocumentDB account, database or collection blades:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/2465.0_7C3ECAA3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/2465.0_5F00_7C3ECAA3.png"><img title="0" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/0312.0_thumb_47323B73.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/0312.0_5F00_thumb_5F00_47323B73.png" alt="0" width="303" height="480" border="0" /></a></p>
<p>With this release, Document Explorer now supports upload of multiple existing JSON documents. Simply open Document <a>Explorer</a> from any of the aforementioned blades and click the &ldquo;Add Document&rdquo; command:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/8726.image_3C08B129.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/8726.image_5F00_3C08B129.png"><img title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/2061.image_thumb_29BFEA67.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/2061.image_5F00_thumb_5F00_29BFEA67.png" alt="image" width="281" height="360" border="0" /></a></p>
<p>A new blade will open. Click the browse button to open a file explorer window and select 1 or more JSON documents to upload. Note that Document Explorer currently supports up to 50 JSON documents per upload operation:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/0827.2_5BB78AF1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/0827.2_5F00_5BB78AF1.png"><img title="2" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/7774.2_thumb_3B9C7E34.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/7774.2_5F00_thumb_5F00_3B9C7E34.png" alt="2" width="610" height="274" border="0" /></a></p>
<p>Once you&rsquo;re satisfied with your selection, click the upload button. The documents will automatically be added to the Document Explorer grid and results will be displayed as the upload operation progresses:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/8345.3_775C16E7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/8345.3_5F00_775C16E7.png"><img title="3" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/2577.3_thumb_2953B772.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/2577.3_5F00_thumb_5F00_2953B772.png" alt="3" width="610" height="387" border="0" /></a></p>
<p>Once the operation has completed, you can select up to another 50 documents to upload.</p>
<p><span>Query Explorer &ndash; Syntax Highlighting</span></p>
<p>Query Explorer allows you to author, edit, and run DocumentDB SQL queries against any of your DocumentDB collections. Similar to Document Explorer, Query Explorer is available from any of the DocumentDB account, database, and collection blades:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/2072.0_1E2A2D28.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/2072.0_5F00_1E2A2D28.png"><img title="0" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4456.0_thumb_0BE16666.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4456.0_5F00_thumb_5F00_0BE16666.png" alt="0" width="303" height="480" border="0" /></a></p>
<p>In this release, we&rsquo;ve enabled basic keyword and value highlighting within Query Explorer to improve the query authoring <a>experience</a> :</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/5545.4_6BC659A8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/5545.4_5F00_6BC659A8.png"><img title="4" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/3482.4_thumb_2B90402E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/3482.4_5F00_thumb_5F00_2B90402E.png" alt="4" width="480" height="392" border="0" /></a></p>
<p><span>Query Explorer &ndash; Rerun queries</span></p>
<p>Finally, we&rsquo;ve modified the Query Explorer blade so that you can run, edit and re-run queries without having to close the results <a>blade</a>:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/6138.5_0B753371.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/6138.5_5F00_0B753371.png"><img title="5" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/metablogapi/4075.5_thumb_4734CC24.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90-metablogapi/4075.5_5F00_thumb_5F00_4734CC24.png" alt="5" width="610" height="285" border="0" /></a></p>
<p>As always, we&rsquo;d love to hear from you about the DocumentDB features and experiences you would find most valuable within the Azure portal.</p>
<p>Please submit your suggestions on the Microsoft Azure DocumentDB <a href="https://feedback.azure.com/forums/263030-documentdb?filter=top&amp;page=1">feedback forum</a>.</p>
<p>If you haven&rsquo;t tried DocumentDB yet, then get started <a href="https://azure.microsoft.com/en-us/services/documentdb/">here</a>.</p>
<p>Enjoy!</p>
<p>Stephen Baron <br />Program Manager</p>]]></content:encoded>
    </item>
    <item>
      <title>Edit and Query documents through the Azure portal</title>
      <link>https://docs.microsoft.com/archive/blogs/documentdb/edit-and-query-documents-through-the-azure-portal</link>
      <pubDate>Fri, 31 Oct 2014 15:24:00 GMT</pubDate>
      <dc:creator><![CDATA[DocumentDB Team]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/documentdb/2014/10/31/edit-and-query-documents-through-the-azure-portal/</guid>
      <description><![CDATA[Edit and Query documents through the Azure portal
We&rsquo;ve released a number of great...]]></description>
      <content:encoded><![CDATA[<p><span style="text-decoration: underline;">Edit and Query documents through the Azure portal</span></p>
<p>We&rsquo;ve released a number of great enhancements to further improve the DocumentDB management experience.&nbsp; Our October 23<sup>rd</sup> portal update lights up the following new capabilities through <a href="https://portal.azure.com/">https://portal.azure.com</a>:</p>
<ul>
<li>Document CRUD operations &ndash; create, edit and delete documents</li>
<li>Document system properties &ndash; view system properties for each document</li>
<li>Document filtering and refresh &ndash; filter and refresh results within Document Explorer</li>
<li>Query Explorer &ndash; author and run DocumentDB SQL queries</li>
</ul>
<p>Keep reading for some additional information on each of these new features!</p>
<p><span style="text-decoration: underline;">Document CRUD operations</span></p>
<p>Document Explorer has been enhanced such that you can create, edit and delete documents.&nbsp; To create a document, simply click the Create Document command and a minimal JSON snippet will be provided:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/6281.1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/6281.1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/6281.1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/6281.1.png" alt="" border="0" /></a></p>
<p>Note that if you choose to not provide an id, Document Explorer will automatically generate a GUID as the id value.&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3580.2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3580.2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3580.2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3580.2.png" alt="" border="0" /></a></p>
<p>Once I click save, the document is updated to reflect the supplied (or generated) id:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/1856.3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/1856.3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/1856.3.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/1856.3.png" alt="" border="0" /></a></p>
<p>Additionally, the document is added to the bottom of the document list in Document Explorer:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3652.4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3652.4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3652.4.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3652.4.png" alt="" border="0" /></a></p>
<p>To edit an existing document, simply select it in Document Explorer, edit the document as you see fit, and click the Save command:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3404.5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3404.5.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3404.5.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3404.5.png" alt="" border="0" /></a></p>
<p>Likewise, you can delete a document by selecting it, clicking the Delete command and then confirming the delete (after confirming, the document will immediately be removed from the Document Explorer list):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2260.6.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2260.6.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2260.6.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2260.6.png" alt="" border="0" /></a></p>
<p>If you&rsquo;re editing a document and decide that you want to discard the edits, simply click the discard command, confirm the discard action, and the previous state of the document will be reloaded:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/7266.7.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/7266.7.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/7266.7.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/7266.7.png" alt="" border="0" /></a></p>
<p>Note that Document Explorer will validate that the document contains valid JSON:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3583.8.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3583.8.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/3583.8.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/3583.8.png" alt="" border="0" /></a></p>
<p>And will also prevent you from saving a document with invalid JSON content:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5315.9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5315.9.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5315.9.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5315.9.png" alt="" border="0" /></a></p>
<p><span style="text-decoration: underline;">Document System Properties</span></p>
<p>We've also added a properties command to Document Explorer which allows you to view the system properties of the currently loaded document:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5327.10.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5327.10.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5327.10.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5327.10.png" alt="" border="0" /></a></p>
<p>Note that the timestamp (_TS) property is internally represented as epoch time but in the portal experience we've converted the display value to a human readable GMT format.</p>
<p><span style="text-decoration: underline;">Document Explorer Filter and Refresh Support</span></p>
<p>Document Explorer now supports filtering the currently loaded set of documents by the id property. Simply type in the filter box:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/4628.11.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/4628.11.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/4628.11.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/280x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/4628.11.png" alt="" border="0" /></a></p>
<p>and the results in the Document Explorer list will be filtered based on your criteria:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/0068.12.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/0068.12.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/0068.12.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/280x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/0068.12.png" alt="" border="0" /></a></p>
<p>&nbsp;Finally, we've added a Refresh command to allow you to easily refresh the documents displayed in Document Explorer:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5241.13.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5241.13.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/5241.13.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/280x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/5241.13.png" alt="" border="0" /></a></p>
<p>&nbsp;<span style="text-decoration: underline;">Query Explorer</span></p>
<p>We&rsquo;re very happy to introduce a new Query Explorer experience which allows you author and run DocumentDB SQL queries.</p>
<p>You can launch Query Explorer from any of the DocumentDB Account, Database, or Collection blades.&nbsp; <br />A default query of SELECT * FROM c is provided in the Query Editor:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/8322.14.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/8322.14.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/8322.14.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/8322.14.png" alt="" border="0" /></a></p>
<p>You can accept the default query or construct your own and then click the Run command to view the results:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2045.15.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2045.15.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2045.15.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2045.15.png" alt="" border="0" /></a></p>
<p>By default, Query Explorer will return results in sets of 100.&nbsp; <br />If your query produces more than 100 results, simply use the Next page and Previous page commands to navigate through the result set:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/0003.16.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/0003.16.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/0003.16.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/0003.16.png" alt="" border="0" /></a></p>
<p>Successful queries will provide information such as the request charge, the set of results currently being shown and whether or not there are more results (which can then be accessed via the Next page command in the results pane):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2043.17.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2043.17.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/2043.17.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/2043.17.png" alt="" border="0" /></a></p>
<p>Likewise, if a query completes with errors, the portal will display a list of errors which can help with troubleshooting efforts:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/7573.18.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/7573.18.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/90/7573.18.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/350x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-90/7573.18.png" alt="" border="0" /></a></p>
<p>As always, we&rsquo;d love to hear from you about the DocumentDB features and experiences you would find most valuable within the Azure portal.&nbsp; Please submit your suggestions on the Microsoft Azure DocumentDB <a href="https://feedback.azure.com/forums/263030-documentdb?filter=top&amp;page=1">feedback forum</a>.&nbsp; If you haven&rsquo;t tried DocumentDB yet, then get started <a href="https://azure.microsoft.com/en-us/services/documentdb/">here</a>.</p>
<p>Enjoy!</p>
<p>Stephen Baron<br /> Program Manager</p>]]></content:encoded>
    </item>
  </channel>
</rss>