I'm trying to patch a single/multiple documents (identified by their id
) with that I receive in a Dictionary<string, object>
. The key of the dictionary is the path to the document property to update, and it may even be a subpath.
So if my document looks like this:
public class MyDoc
{
public string StringProp {get; set;}
public bool? BoolProp {get; set;}
public int? IntProp {get; set;}
public SubDocument SubProp {get; set;}
}
public class SubDocument
{
public string StringProp {get; set;}
}
So an example Dictionary may be:
new Dictionary<string, object>
{
{"StringProp", "hello" },
{"BoolProp", true },
{"SubProp.StringProp", "subprop value" },
}
I know how to fetch the document(s), apply the dictionary to it and save the document(s), but I'm looking for a way that doesn't require the extraction of the documents I want to modify.
I'm guessing it would go something along these lines:
var operation = store
.Operations
.Send(new PatchByQueryOperation(new IndexQuery
{
QueryParameters = new Parameters
{
{"ids", new[] {"orders/1-A", "companies/1-A"}}
},
Query = @"from @all_docs as d where id() in ($ids)
update
{
d.StringProp = 'hello';
d.BoolProp = true;
d.SubProp.StringProp = 'subprop value';
}"
}));
And what if SubProp
doesn't exist on a document or if I'd like to assign the entire SubProp
rather than just fill a property on a subdocument?
Regarding your second Question about:
"assigning the entire SubProp rather than just filling a property on a subdocument"
The following will work:
var subObject = new SubDocument() {StringProp = "new sub text"};
var operation = store.Operations.Send(new PatchByQueryOperation(new IndexQuery
{
QueryParameters = new Parameters
{
{ "ids", new[] {"myDocs/1", "companies/1-A"} },
{ "subObject", subObject }
},
Query = @"from @all_docs as d where id() in ($ids)
update
{
d.StringProp = 'hello';
d.BoolProp = false;
d.SubProp = ($subObject);
}"
}));
Regarding your first Question about:
"what if SubProp doesn't exist on a document"
1.
Patching with d.SubProp = 'value1'
when SubProp
doesn't exist, will succeed and property SubProp
will be created with value1
.
2.
Patching with d.SubProp.StringProp = 'value2'
will only succeed if property SubProp
is an object type (not a string).
If you need to patch only a single document, then you don't have to use set-based patching.
You can use single-document patching.
Single-document patching is explained by these articles:
(Note: the Node.js article is currently more organized and detailed, the C# article is TBD,
however logic behind is the same)
https://ravendb.net/docs/article-page/latest/nodejs/client-api/operations/patching/single-document https://ravendb.net/docs/article-page/latest/csharp/client-api/operations/patching/single-document
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