Skip to content

Commit 89cb19f

Browse files
authored
Add document:upsert (#576)
1 parent ecbe1d7 commit 89cb19f

File tree

6 files changed

+128
-1
lines changed

6 files changed

+128
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
code: true
3+
type: page
4+
title: upsert
5+
description: Applies partial changes to a document. If the document doesn't already exist, a new document is created.
6+
---
7+
8+
# upsert
9+
10+
<SinceBadge version="Kuzzle 2.8.0"/>
11+
<SinceBadge version="auto-version" />
12+
13+
Applies partial changes to a document. If the document doesn't already exist, a new document is created.
14+
15+
16+
```js
17+
upsert(index, collection, id, changes, [options]);
18+
```
19+
20+
| Argument | Type | Description |
21+
| ------------ | ----------------- | ----------------------------------------- |
22+
| `index` | <pre>string</pre> | Index name |
23+
| `collection` | <pre>string</pre> | Collection name |
24+
| `id` | <pre>string</pre> | Document ID |
25+
| `changes` | <pre>object</pre> | Partial content of the document to update |
26+
27+
### Options
28+
29+
Additional query options
30+
31+
| Options | Type<br/>(default) | Description |
32+
| ----------------- | ------------------------------- | ---------------------------------------------------------------------------------- |
33+
| `defaults` | <pre>object</pre><br/>(`{}`) | Fields to add to the document if it gets created |
34+
| `refresh` | <pre>string</pre><br/>(`""`) | If set to `wait_for`, waits for the change to be reflected for `search` (up to 1s) |
35+
| `retryOnConflict` | <pre>int</pre><br/>(`10`) | The number of times the database layer should retry in case of version conflict |
36+
| `source` | <pre>boolean</pre><br/>(`false`)| If true, returns the updated document inside the response
37+
38+
39+
## Resolves
40+
41+
Resolves to an object containing the document update result.
42+
43+
## Usage
44+
45+
<<< ./snippets/upsert.js
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
try {
2+
await kuzzle.document.create(
3+
'nyc-open-data',
4+
'yellow-taxi',
5+
{ capacity: 4 },
6+
'some-id'
7+
);
8+
9+
const response = await kuzzle.document.upsert(
10+
'nyc-open-data',
11+
'yellow-taxi',
12+
'some-id',
13+
{ changes: { category: 'suv' } }
14+
);
15+
16+
console.log(response);
17+
/*
18+
{
19+
id: 'some-id',
20+
_version: 2
21+
}
22+
*/
23+
} catch (error) {
24+
console.error(error.message);
25+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: document#upsert
2+
description: Applies a partial update to an existing document.
3+
hooks:
4+
before: |
5+
curl -XDELETE kuzzle:7512/nyc-open-data
6+
curl -XPOST kuzzle:7512/nyc-open-data/_create
7+
curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi
8+
after:
9+
template: default
10+
expected: "_id: 'some-id'"

src/Kuzzle.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,10 @@ export class Kuzzle extends KuzzleEventEmitter {
543543
request.refresh = options.refresh;
544544
}
545545

546+
if (request.retryOnConflict === undefined && options.retryOnConflict !== undefined) {
547+
request.retryOnConflict = options.retryOnConflict;
548+
}
549+
546550
if (! request.volatile) {
547551
request.volatile = this.volatile;
548552
}

src/controllers/Document.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,43 @@ export class DocumentController extends BaseController {
778778
.then(response => response.result);
779779
}
780780

781+
/**
782+
* Applies a partial update to an existing document.
783+
* If the document doesn't already exist, a new document is created.
784+
* @see https://docs.kuzzle.io/sdk/js/7/controllers/document/upsert/
785+
*
786+
* @param index Index name
787+
* @param collection Collection name
788+
* @param _id Unique document identifier
789+
* @param changes Partial content of the document to update
790+
* @param [options]
791+
* - `defaults` Fields to add to the document if it gets created
792+
* - `refresh` If set to `wait_for`, Kuzzle will not respond until the API key is indexed
793+
* - `retryOnConflict` Number of times the database layer should retry in case of version conflict
794+
* - `source` If true, returns the updated document inside the response
795+
*
796+
* @returns Information about the updated document
797+
*/
798+
upsert (
799+
index: string,
800+
collection: string,
801+
_id: string,
802+
changes: JSONObject,
803+
options: {defaults?: JSONObject; refresh?: string, retryOnConflict?: boolean, source?: boolean} = {}
804+
): Promise<Document> {
805+
const request = {
806+
index,
807+
collection,
808+
_id,
809+
body: { changes, defaults: options.defaults },
810+
action: 'upsert',
811+
source: options.source
812+
};
813+
814+
return this.query(request, options)
815+
.then(response => response.result);
816+
}
817+
781818
/**
782819
* Validates a document against existing validation rules.
783820
*

src/types/Document.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ export class Document {
4848
* Document Version (generated by Elasticsearch)
4949
*/
5050
_version?: number;
51+
/**
52+
* If true, a new document was created,
53+
* otherwise the document existed and was updated
54+
* @see https://docs.kuzzle.io/sdk/js/7/controllers/document/upsert/
55+
*/
56+
created?: boolean;
5157
/**
5258
* Document Content
5359
*/
@@ -69,4 +75,4 @@ export interface DocumentHit extends Document {
6975
* Relevance score
7076
*/
7177
_score: number;
72-
}
78+
}

0 commit comments

Comments
 (0)