diff --git a/docs/client-api/operations/patching/content/_single-document-csharp.mdx b/docs/client-api/operations/patching/content/_single-document-csharp.mdx
index bf60a8e46f..67bb97bb03 100644
--- a/docs/client-api/operations/patching/content/_single-document-csharp.mdx
+++ b/docs/client-api/operations/patching/content/_single-document-csharp.mdx
@@ -300,6 +300,7 @@ See the more comprehensive list at [Knowledge Base: JavaScript Engine](../../../
| **deleteCounter** | Document; counter name | Deletes the counter |
| **spatial.distance** | Two points by latitude and longitude; spatial units | Find the distance between to points on the earth |
| **timeseries** | Document; the time series' name | Returns the specified time series object |
+| **attachments** | Document; attachment name | Returns an attachment object providing `delete()`, `remote()`, and `copyFrom()` methods for managing the specified attachment via patching |
@@ -997,9 +998,12 @@ session.SaveChanges();
* When cloning a document via patching, only the document's fields are copied to the new document.
Attachments, counters, time series data, and revisions from the source document will Not be copied automatically.
- * To manage time series & counters via patching, you can use the pre-defined JavaScript methods listed here:
- [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations) & [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
- * Note: When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
+ * To manage counters, time series, and attachments via patching, you can use the pre-defined JavaScript methods listed here:
+ * [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations)
+ * [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
+ * [Attachments methods](../../../../server/kb/javascript-engine.mdx#attachment-operations).
+ * Note:
+ When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
attachments, counters, time Series, and revisions will be copied automatically.
**Archived documents:**
diff --git a/docs/client-api/operations/patching/content/_single-document-java.mdx b/docs/client-api/operations/patching/content/_single-document-java.mdx
index 450920f197..564f1bc0d2 100644
--- a/docs/client-api/operations/patching/content/_single-document-java.mdx
+++ b/docs/client-api/operations/patching/content/_single-document-java.mdx
@@ -185,6 +185,7 @@ more comprehensive list at [Knowledge Base: JavaScript Engine](../../../../serve
| **counterRaw** | Document; counter name | Returns the specified counter in the specified document as a key-value pair |
| **incrementCounter** | Document; counter name | Increases the value of the counter by one |
| **deleteCounter** | Document; counter name | Deletes the counter |
+| **attachments** | Document; attachment name | Returns an attachment object providing `delete()`, `remote()`, and `copyFrom()` methods for managing the specified attachment via patching |
@@ -650,9 +651,12 @@ store.operations().send(new PatchOperation("employees/1-A", null, patchRequest))
* When cloning a document via patching, only the document's fields are copied to the new document.
Attachments, counters, time series data, and revisions from the source document will Not be copied automatically.
- * To manage time series & counters via patching, you can use the pre-defined JavaScript methods listed here:
- [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations) & [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
- * Note: When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
+ * To manage counters, time series, and attachments via patching, you can use the pre-defined JavaScript methods listed here:
+ * [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations)
+ * [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
+ * [Attachments methods](../../../../server/kb/javascript-engine.mdx#attachment-operations).
+ * Note:
+ When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
attachments, counters, time Series, and revisions will be copied automatically.
**Archived documents:**
diff --git a/docs/client-api/operations/patching/content/_single-document-nodejs.mdx b/docs/client-api/operations/patching/content/_single-document-nodejs.mdx
index 4f25211372..c939ef8e3f 100644
--- a/docs/client-api/operations/patching/content/_single-document-nodejs.mdx
+++ b/docs/client-api/operations/patching/content/_single-document-nodejs.mdx
@@ -1086,9 +1086,12 @@ await documentStore.operations.send(patchOp);
* When cloning a document via patching, only the document's fields are copied to the new document.
Attachments, counters, time series data, and revisions from the source document will Not be copied automatically.
- * To manage time series & counters via patching, you can use the pre-defined JavaScript methods listed here:
- [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations) & [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
- * Note: When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
+ * To manage counters, time series, and attachments via patching, you can use the pre-defined JavaScript methods listed here:
+ * [Counters methods](../../../../server/kb/javascript-engine.mdx#counter-operations)
+ * [Time series methods](../../../../server/kb/javascript-engine.mdx#time-series-operations).
+ * [Attachments methods](../../../../server/kb/javascript-engine.mdx#attachment-operations).
+ * Note:
+ When [Cloning a document via the Studio](../../../../studio/database/documents/create-new-document.mdx#clone-an-existing-document),
attachments, counters, time Series, and revisions will be copied automatically.
**Archived documents:**
diff --git a/docs/document-extensions/attachments/content/_copy-move-rename-csharp.mdx b/docs/document-extensions/attachments/content/_copy-move-rename-csharp.mdx
index d393242d57..f354a1cf56 100644
--- a/docs/document-extensions/attachments/content/_copy-move-rename-csharp.mdx
+++ b/docs/document-extensions/attachments/content/_copy-move-rename-csharp.mdx
@@ -12,6 +12,8 @@ import Panel from '@site/src/components/Panel';
* In this article:
* [Copy attachment to another document](../../../document-extensions/attachments/copy-move-rename.mdx#copy-attachment-to-another-document)
+ * [Copy attachment - via the session](../../../document-extensions/attachments/copy-move-rename.mdx#copy-attachments---via-the-session)
+ * [Copy attachment - via patching](../../../document-extensions/attachments/copy-move-rename.mdx#copy-attachments---via-patching)
* [Move attachment to another document](../../../document-extensions/attachments/copy-move-rename.mdx#move-attachment-to-another-document)
* [Rename attachment](../../../document-extensions/attachments/copy-move-rename.mdx#rename-attachment)
* [Syntax](../../../document-extensions/attachments/copy-move-rename.mdx#syntax)
@@ -20,9 +22,6 @@ import Panel from '@site/src/components/Panel';
-* Use the session's `Advanced.Attachments.Copy` method to copy an attachment from one document to another.
- You can assign any name to the copied attachment in the target document, it doesn't have to match the source name.
-
* **Copying LOCAL attachments**:
The target document's metadata is updated to reference the same attachment.
The binary content is Not duplicated, it remains stored once in the database,
@@ -33,7 +32,14 @@ import Panel from '@site/src/components/Panel';
The attachment is Not re-uploaded or duplicated in the remote destination,
even if the copied attachment has a different name in the target document.
-* An exception is thrown in any of the following cases:
+---
+
+### Copy attachments - via the session
+
+* Use the session's `Advanced.Attachments.Copy` method to copy an attachment from one document to another.
+ You can assign any name to the copied attachment in the target document, it doesn't have to match the source name.
+
+* **An exception is thrown** in any of the following cases:
* The source document does not exist.
* The destination document does not exist.
* The specified attachment is not found in the source document.
@@ -84,6 +90,84 @@ using (var asyncSession = store.OpenAsyncSession())
+---
+
+### Copy attachments - via patching
+
+* Use `attachments(targetDocument, targetAttachmentName).copyFrom(sourceDocId, sourceAttachmentName)` to copy an attachment between documents within a patch script.
+ The method copies the attachment from the source document and assigns it to the target document under the specified name.
+
+* In both [single-document patches](../../../client-api/operations/patching/single-document.mdx)
+ and [patch-by-query operations](../../../client-api/operations/patching/set-based.mdx),
+ the copy is performed entirely server-side,
+ without requiring the attachment to be downloaded and re-uploaded through the client.
+
+* **An exception is thrown** in the following case:
+ * An attachment with the specified name already exists on the target document.
+
+* **No exception is thrown** in the following cases:
+ * The source document does not exist.
+ * The source attachment does not exist.
+ * The destination document does not exist.
+
+
+
+```csharp
+// Define the patch request
+var patchRequest = new PatchRequest
+{
+ // Copy attachment 'photo.jpg' from 'employees/1' to the patched document
+ // and name it 'photo-copy.jpg' in the target document
+ Script = "attachments(this, args.targetName).copyFrom(args.sourceDocId, args.sourceName);",
+ Values =
+ {
+ { "sourceDocId", "employees/1" },
+ { "sourceName", "photo.jpg" },
+ { "targetName", "photo-copy.jpg" }
+ }
+};
+
+// Execute the patch operation on the target document
+store.Operations.Send(new PatchOperation("employees/2", null, patchRequest));
+```
+
+
+```csharp
+// Define the patch request
+var patchRequest = new PatchRequest
+{
+ // Copy attachment 'photo.jpg' from 'employees/1' to the patched document
+ // and name it 'photo-copy.jpg' in the target document
+ Script = "attachments(this, args.targetName).copyFrom(args.sourceDocId, args.sourceName);",
+ Values =
+ {
+ { "sourceDocId", "employees/1" },
+ { "sourceName", "photo.jpg" },
+ { "targetName", "photo-copy.jpg" }
+ }
+};
+
+// Execute the patch operation asynchronously on the target document
+await store.Operations.SendAsync(new PatchOperation("employees/2", null, patchRequest));
+```
+
+
+```csharp
+// Copy an attachment to ALL documents in a collection using a patch-by-query operation
+var op = store.Operations.Send(new PatchByQueryOperation(new IndexQuery
+{
+ Query = @"
+ from Employees as e
+ update {
+ attachments(e, 'photo-copy.jpg').copyFrom('employees/1', 'photo.jpg');
+ }"
+}));
+
+op.WaitForCompletion();
+```
+
+
+
@@ -260,5 +344,29 @@ void Rename(string documentId, string name, string newName);
| **documentId** | `string` | The document ID that holds the attachment. |
| **name** | `string` | The current name of the attachment. |
| **newName** | `string` | The new name to assign to the attachment. |
+
+---
+
+#### Copy attachment via patch script
+
+
+```javascript
+attachments(document, attachmentName).copyFrom(sourceDocId, sourceName)
+```
+
+
+| Parameter | Type | Description |
+|--------------------|----------|-------------|
+| **document** | `object` | The target document entity (use `this` for the current document being patched). |
+| **attachmentName** | `string` | The name to assign to the copied attachment in the target document. |
+| **sourceDocId** | `string` | The ID of the source document that holds the attachment to copy. |
+| **sourceName** | `string` | The name of the attachment to copy from the source document. |
+
+| Return value | Description |
+|--------------|-------------|
+| `true` | The attachment was copied successfully. |
+| `false` | The source document or the source attachment was not found. No exception is thrown. |
+
+See [JavaScript engine](../../../server/kb/javascript-engine.mdx) for the full list of JavaScript methods available in RavenDB.
\ No newline at end of file
diff --git a/docs/server/kb/javascript-engine.mdx b/docs/server/kb/javascript-engine.mdx
index 1eefdb8215..600cf980e7 100644
--- a/docs/server/kb/javascript-engine.mdx
+++ b/docs/server/kb/javascript-engine.mdx
@@ -128,10 +128,11 @@ RavenDB provides the following set of predefined functions:
### **Attachment operations**:
-| Method Signature | Return type | Description |
-|-----------------------------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------------------------------|
-| **attachments(document, attachmentName).remote(destinationID, uploadTime)** | `void` | Updates the document's metadata with remote parameters to schedule the attachment for upload to remote storage.
See [Schedule attachment for remote upload](../../document-extensions/attachments/store-attachments/store-attachments-remote.mdx#schedule-existing-attachments-for-remote-upload). |
-| **attachments(document, attachmentName).delete()** | `void` | Deletes the specified attachment from the document.
See [Delete attachment via patching](../../document-extensions/attachments/delete-attachment.mdx#delete-attachment---via-a-patch). |
+| Method Signature | Return type | Description |
+|----------------------------------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------------------------------|
+| **attachments(document, attachmentName)
.remote(destinationID, uploadTime)** | `void` | Updates the document's metadata with remote parameters to schedule the attachment for upload to remote storage.
See [Schedule attachment for remote upload](../../document-extensions/attachments/store-attachments/store-attachments-remote.mdx#schedule-existing-attachments-for-remote-upload). |
+| **attachments(document, attachmentName)
.delete()** | `void` | Deletes the specified attachment from the document.
See [Delete attachment via patching](../../document-extensions/attachments/delete-attachment.mdx#delete-attachment---via-a-patch). |
+| **attachments(targetDocument, targetAttachmentName)
.copyFrom(sourceDocId, sourceName)** | `boolean` | Copies an attachment from a source document to the target document with the specified name.
Returns `true` on success, `false` if the source attachment does not exist.
See [Copy attachment via patching](../../document-extensions/attachments/copy-move-rename.mdx#copy-attachments---via-patching). |
---