Please look at the code first.
In step 8, the field is not updated. In step 11&12, the field is updated.
I have 2 questions.
What is the difference between ReadDocumentAsync and CreateDocumentQuery when replacing?
Is it appropriate to use the value obtained by DocumentQuery for replacement?
ConsoleApp
NuGet Package(Microsoft.Azure.DocumentDB 1.19.1,Newtonsoft.Json 9.0.1)
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;
class Program
{
static string endpoint = ConfigurationManager.AppSettings["endpoint"];
static string key = ConfigurationManager.AppSettings["key"];
static string database = ConfigurationManager.AppSettings["database"];
static string collection = ConfigurationManager.AppSettings["collection"];
static void Main(string[] args)
{
ConnectionPolicy cp = new ConnectionPolicy()
{
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Https,
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 5,
MaxRetryWaitTimeInSeconds = 60,
}
};
var client = new DocumentClient(new Uri(endpoint), key, cp);
//Step1 Create Database
client.CreateDatabaseIfNotExistsAsync(new Database { Id = database }).Wait();
//Step2 Create Collection(400RU)
client.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(database),
new DocumentCollection
{
Id = collection,
PartitionKey = new PartitionKeyDefinition()
{ Paths = new Collection<string>() { "/partitionKey" } }
}
, new RequestOptions { OfferThroughput = 400 }).Wait();
//Step3 Insert TestData
var id1 = Guid.NewGuid().ToString();
client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collection)
, new TestDocument() { TestField = "initialvalue", PartitionKey = "default", Id = id1, }).Wait();
var id2 = Guid.NewGuid().ToString();
client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collection)
, new TestDocument() { TestField = "initialvalue", PartitionKey = "default", Id = id2, }).Wait();
//Step4 ID1 GetDocument(ReadDocument)
var readDocument = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id1),
new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
//Step5 ID2 GetDocument(DocumentQuery)
var queryDocument = client.CreateDocumentQuery<TestDocument>(UriFactory.CreateDocumentCollectionUri(database, collection),
new FeedOptions { MaxItemCount = 1, EnableCrossPartitionQuery = false, })
.Where(x => x.PartitionKey == "default" && x.Id == id2)
.AsDocumentQuery().ExecuteNextAsync<TestDocument>().Result.FirstOrDefault();
//Step6 ChangeValue
readDocument.TestField = "newvalue";
queryDocument.TestField = "newvalue";
//Step7 ID1 Replace
var updateResult1 = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, readDocument.Id), readDocument).Result;
//Step8 ID2 Replace
var updateResult2 = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, queryDocument.Id), queryDocument).Result;
//Step9 ID1 select
var id1Updated = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id1),
new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
//Step10 ID2 select
var id2Updated = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id2),
new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
Console.WriteLine(id1Updated.TestField); //newvalue
Console.WriteLine(id2Updated.TestField); //initialvalue
Console.ReadLine();
//Step11 ID2 SetPropertyValue
queryDocument.SetPropertyValue("testField", "newvalue2");
//Step12 ID2 Replace
var updateResultX = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, queryDocument.Id), queryDocument).Result;
//Step13 ID2 select
var id2UpdatedX = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id2),
new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
Console.WriteLine(id2UpdatedX.TestField); //newvalue2
Console.ReadLine();
}
}
public class TestDocument : Document
{
[JsonProperty("partitionKey")]
public string PartitionKey { get; set; }
[JsonProperty("testField")]
public string TestField { get; set; }
}
What is the difference between ReadDocumentAsync and CreateDocumentQuery when replacing?
You should use ReadDocumentAsync over a query for simple ID lookups.
On the server side, a ReadDocumentAsync (GET on REST API) is more lightweight in terms of throughput (RUs) and latency. There's no SQL parsing/compilation/index scans, it's just a direct lookup.
ReadDocumentAsync will throw that DocumentClientException when it can't find the specific document (returning a 404 in the status code) which is mentioned here.
To get around dealing with this exception, you could make a query instead of a direct read, by using CreateDocumentQuery() first.Then, you'll simply get a result set.
Is it appropriate to use the value obtained by DocumentQuery for replacement?
Yes, you could use the docuemnt obtained by DocumentQuery to do replace operations. Please refer to the snippet of code as below:
private async Task updateDoc()
{
string EndpointUri = "xxxxx";
string PrimaryKey = "xxxxx";
DocumentClient client;
client = new DocumentClient(new Uri(EndpointUri), PrimaryKey);
Document doc = client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri("db", "coll"))
.Where(r => r.Id == "**")
.AsEnumerable()
.SingleOrDefault();
MyMode mode= (dynamic)doc;
mode.name = "updated value";
//replace document
Document updateddoc = await client.ReplaceDocumentAsync(doc.SelfLink, mode);
Console.WriteLine(updateddoc);
}
public class MyMode
{
public string id { get; set; }
public string name { get; set; }
}
Hope it helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With