Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .ci/doc/templates/print-result-successes.tpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Loads the Kuzzle SDK module and the websocket protocol
const {
Kuzzle,
WebSocket
} = require('kuzzle-sdk');

// Instantiates a Kuzzle client
const
kuzzle = new Kuzzle(
new WebSocket('kuzzle', { autoReconnect: false })
);

// Adds a listener to detect connection problems
kuzzle.on('networkError', error => {
console.error(`Network Error: ${error.message}`);
});

(async () => {
let result;
try {
await kuzzle.connect();
} catch (error) {
console.log(`Cannot connect to Kuzzle: ${error.message}`);
}
[snippet-code] finally {
kuzzle.disconnect();
}
for (const elem of result.successes) {
console.log(elem);
}
})();
64 changes: 64 additions & 0 deletions doc/7/controllers/document/update-by-query/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
code: true
type: page
title: updateByQuery
description: Updates documents matching query
---

# updateByQuery

Updates documents matching the provided search query.

Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax.

An empty or null query will match all documents in the collection.

<br/>

```js
updateByQuery(index, collection, searchQuery, changes, [options])
```

| Argument | Type | Description |
| ------------------ | -------------------------------------------- | --------------- |
| `index` | <pre>string</pre> | Index name |
| `collection` | <pre>string</pre> | Collection name |
| `searchQuery` | <pre>object</pre> | Query to match |
| `changes` | <pre>object</pre> | Partial changes to apply to the documents |
| `options` | <pre>object</pre> | Optional parameters |

---

### options

Additional query options.

| Options | Type<br/>(default) | Description |
| ----------------- | ------------------------------- | ---------------------------------------------------------------------------------- |
| `refresh` | <pre>string</pre><br/>(`""`) | If set to `wait_for`, waits for the change to be reflected for `search` (up to 1s) |
| `source` | <pre>boolean</pre><br/>(`false`)| If true, returns the updated document inside the response

## Resolves

Returns an object containing 2 arrays: `successes` and `errors`

Each updated document is an object of the `successes` array with the following properties:

| Property | Type | Description |
|------------- |--------------------------------------------- |--------------------------------- |
| `_source` | <pre>object<String, Object></pre> | Updated document (if `source` option set to true) |
| `_id` | <pre>string</pre> | ID of the udated document |
| `_version` | <pre>number</pre> | Version of the document in the persistent data storage |
| `status` | <pre>number</pre> | HTTP status code |

Each errored document is an object of the `errors` array with the following properties:

| Property | Type | Description |
|------------- |--------------------------------------------- |--------------------------------- |
| `document` | <pre>object<String, Object></pre> | Document that causes the error |
| `status` | <pre>number</pre> | HTTP error status |
| `reason` | <pre>string</pre> | Human readable reason |

## Usage

<<< ./snippets/update-by-query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
try {
result = await kuzzle.document.updateByQuery(
'nyc-open-data',
'yellow-taxi',
{
match: {
capacity: 4
}
}, {
capacity: 42
});
/*
{
successes: [
{
_id: <document-id>,
_source: <updated document> // if source set to true
status: 200
},
{
_id: <document id>,
_source: <updated document> // if source set to true
status: 200
}
],
errors: []
}
*/
} catch (error) {
console.log(error.message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: document#updateByQuery
description: Update documents matching query
hooks:
before: |
curl -XDELETE kuzzle:7512/nyc-open-data
curl -XPOST kuzzle:7512/nyc-open-data/_create
curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi
for i in 1 2 ; do
curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create
done
for i in 1 2 3 4 5; do
curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create
done
curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh
after:
template: print-result-successes
expected:
- "{ _id: 'document_1', _version: 2, status: 200 }"
- "{ _id: 'document_2', _version: 2, status: 200 }"
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"babel-loader": "^8.1.0",
"codecov": "^3.6.5",
"codecov": "^3.7.0",
"cucumber": "^6.0.5",
"eslint": "^6.8.0",
"eslint-friendly-formatter": "^4.0.1",
Expand Down
13 changes: 13 additions & 0 deletions src/controllers/Document.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ class DocumentController extends BaseController {
.then(response => response.result);
}

updateByQuery(index, collection, searchQuery, changes, options = {}) {
const request = {
index,
collection,
body: {query: searchQuery, changes},
action: 'updateByQuery',
source: options.source
};

return this.query(request, options)
.then(response => response.result);
}

validate (index, collection, body, options = {}) {
return this.query({
index,
Expand Down
4 changes: 4 additions & 0 deletions src/protocols/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@
"url": "/:index/:collection/:_id/_update",
"verb": "PUT"
},
"updateByQuery": {
"url": "/:index/:collection/_query",
"verb": "PUT"
},
"mUpdate": {
"url": "/:index/:collection/_mUpdate",
"verb": "PUT"
Expand Down
81 changes: 80 additions & 1 deletion test/controllers/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,86 @@ describe('Document Controller', () => {
body: { foo: 'bar' },
retryOnConflict: undefined,
source: true
}, { source: true });
});

should(res).be.equal(result);
});
});
});

describe('updateByQuery', () => {
it('should call document/update query and return a Promise which resolves the updated document', () => {
const result = {
_id: 'document-id',
_version: 1,
_source: { foo: 'bar' },
created: false
};
kuzzle.query.resolves({ result });
const searchQuery = {
match: { foo: 'bar' }
};
const changes = {
bar: 'foo'
};
return kuzzle.document.updateByQuery('index', 'collection', searchQuery, changes, options)
.then(res => {
should(kuzzle.query)
.be.calledOnce()
.be.calledWith({
controller: 'document',
action: 'updateByQuery',
index: 'index',
collection: 'collection',
body: {
query: {
match: {foo: 'bar'}
},
changes: {
bar: 'foo'
}
},
source: undefined
}, options);

should(res).be.equal(result);
});
});

it('should inject the "source" option into the request', () => {
const result = {
_id: 'document-id',
_version: 1,
_source: { foo: 'bar' },
created: false
};
kuzzle.query.resolves({ result });
const searchQuery = {
match: { foo: 'bar' }
};
const changes = {
bar: 'foo'
};

return kuzzle.document.updateByQuery('index', 'collection', searchQuery, changes, { source: true })
.then(res => {
should(kuzzle.query)
.be.calledOnce()
.be.calledWith({
controller: 'document',
action: 'updateByQuery',
index: 'index',
collection: 'collection',
body: {
query: {
match: { foo: 'bar' }
},
changes: {
bar: 'foo'
}
},
source: true
});

should(res).be.equal(result);
});
Expand Down