Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix document:search command #67

Merged
merged 6 commits into from
Oct 20, 2020
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
120 changes: 61 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Then any argument will be passed as-is to the `sdk:query` method.
* [`kourou collection:export INDEX COLLECTION`](#kourou-collectionexport-index-collection)
* [`kourou collection:import PATH`](#kourou-collectionimport-path)
* [`kourou config:diff FIRST SECOND`](#kourou-configdiff-first-second)
* [`kourou document:search INDEX COLLECTION`](#kourou-documentsearch-index-collection)
* [`kourou document:search INDEX COLLECTION [QUERY]`](#kourou-documentsearch-index-collection-query)
* [`kourou es:get INDEX ID`](#kourou-esget-index-id)
* [`kourou es:insert INDEX`](#kourou-esinsert-index)
* [`kourou es:list-index`](#kourou-eslist-index)
Expand All @@ -147,11 +147,11 @@ Then any argument will be passed as-is to the `sdk:query` method.
* [`kourou instance:spawn`](#kourou-instancespawn)
* [`kourou profile:export`](#kourou-profileexport)
* [`kourou profile:import PATH`](#kourou-profileimport-path)
* [`kourou realtime:subscribe INDEX COLLECTION`](#kourou-realtimesubscribe-index-collection)
* [`kourou role:export`](#kourou-roleexport)
* [`kourou role:import PATH`](#kourou-roleimport-path)
* [`kourou sdk:execute`](#kourou-sdkexecute)
* [`kourou sdk:query CONTROLLER:ACTION`](#kourou-sdkquery-controlleraction)
* [`kourou subscribe INDEX COLLECTION`](#kourou-subscribe-index-collection)
* [`kourou user:export`](#kourou-userexport)
* [`kourou user:export-mappings`](#kourou-userexport-mappings)
* [`kourou user:import PATH`](#kourou-userimport-path)
Expand Down Expand Up @@ -417,17 +417,18 @@ EXAMPLE

_See code: [src/commands/config/diff.ts](src/commands/config/diff.ts)_

## `kourou document:search INDEX COLLECTION`
## `kourou document:search INDEX COLLECTION [QUERY]`

Searches for documents

```
USAGE
$ kourou document:search INDEX COLLECTION
$ kourou document:search INDEX COLLECTION [QUERY]

ARGUMENTS
INDEX Index name
COLLECTION Collection name
QUERY Query in JS or JSON format.

OPTIONS
--api-key=api-key Kuzzle user api-key
Expand All @@ -439,15 +440,14 @@ OPTIONS
--password=password Kuzzle user password
--port=port [default: 7512] Kuzzle server port
--protocol=protocol [default: http] Kuzzle protocol (http or ws)
--query=query [default: {}] Query in JS or JSON format.
--scroll=scroll Optional scroll TTL
--size=size Optional page size
--sort=sort [default: {}] Sort in JS or JSON format.
--ssl Use SSL to connect to Kuzzle
--username=username [default: anonymous] Kuzzle username (local strategy)

EXAMPLES
kourou document:search iot sensors --query '{ term: { name: "corona" } }'
kourou document:search iot sensors '{ term: { name: "corona" } }'
kourou document:search iot sensors --editor
```

Expand Down Expand Up @@ -785,6 +785,59 @@ OPTIONS

_See code: [src/commands/profile/import.ts](src/commands/profile/import.ts)_

## `kourou realtime:subscribe INDEX COLLECTION`

Subscribes to realtime notifications

```
USAGE
$ kourou realtime:subscribe INDEX COLLECTION

ARGUMENTS
INDEX Index name
COLLECTION Collection name

OPTIONS
--api-key=api-key Kuzzle user api-key
--as=as Impersonate a user

--display=display [default: result] Path of the property to display from the notification (empty string to display
everything)

--editor Open an editor (EDITOR env variable) to edit the filters before subscribing.

--filters=filters [default: {}] Set of Koncorde filters

--help show CLI help

--host=host [default: localhost] Kuzzle server host

--password=password Kuzzle user password

--port=port [default: 7512] Kuzzle server port

--protocol=protocol [default: websocket] Kuzzle protocol (only websocket for realtime)

--scope=scope [default: all] Subscribe to document entering or leaving the scope (all, in, out, none)

--ssl Use SSL to connect to Kuzzle

--username=username [default: anonymous] Kuzzle username (local strategy)

--users=users [default: all] Subscribe to users entering or leaving the room (all, in, out, none)

--volatile=volatile [default: {}] Additional subscription information used in user join/leave notifications

EXAMPLES
kourou realtime:subscribe iot-data sensors
kourou realtime:subscribe iot-data sensors --filters '{ range: { temperature: { gt: 0 } } }'
kourou realtime:subscribe iot-data sensors --filters '{ exists: "position" }' --scope out
kourou realtime:subscribe iot-data sensors --users all --volatile '{ clientId: "citizen-kane" }'
kourou realtime:subscribe iot-data sensors --display result._source.temperature
```

_See code: [src/commands/realtime/subscribe.ts](src/commands/realtime/subscribe.ts)_

## `kourou role:export`

Exports roles
Expand Down Expand Up @@ -967,6 +1020,7 @@ DESCRIPTION
and action as first argument.
Kourou will try to infer the first arguments to one the following pattern:
- <command> <index>
- <command> <body>
- <command> <index> <collection>
- <command> <index> <collection> <id>
- <command> <index> <collection> <body>
Expand All @@ -976,6 +1030,7 @@ DESCRIPTION

Examples:
- kourou collection:list iot
- kourou security:createUser '{"content":{"profileIds":["default"]}}' --id yagmur
- kourou collection:delete iot sensors
- kourou document:createOrReplace iot sensors sigfox-1 '{}'
- kourou bulk:import iot sensors '{bulkData: [...]}'
Expand All @@ -984,59 +1039,6 @@ DESCRIPTION

_See code: [src/commands/sdk/query.ts](src/commands/sdk/query.ts)_

## `kourou subscribe INDEX COLLECTION`

Subscribes to realtime notifications

```
USAGE
$ kourou subscribe INDEX COLLECTION

ARGUMENTS
INDEX Index name
COLLECTION Collection name

OPTIONS
--api-key=api-key Kuzzle user api-key
--as=as Impersonate a user

--display=display [default: result] Path of the property to display from the notification (empty string to display
everything)

--editor Open an editor (EDITOR env variable) to edit the filters before subscribing.

--filters=filters [default: {}] Set of Koncorde filters

--help show CLI help

--host=host [default: localhost] Kuzzle server host

--password=password Kuzzle user password

--port=port [default: 7512] Kuzzle server port

--protocol=protocol [default: websocket] Kuzzle protocol (only websocket for realtime)

--scope=scope [default: all] Subscribe to document entering or leaving the scope (all, in, out, none)

--ssl Use SSL to connect to Kuzzle

--username=username [default: anonymous] Kuzzle username (local strategy)

--users=users [default: all] Subscribe to users entering or leaving the room (all, in, out, none)

--volatile=volatile [default: {}] Additional subscription information used in user join/leave notifications

EXAMPLES
kourou subscribe iot-data sensors
kourou subscribe iot-data sensors --filters '{ range: { temperature: { gt: 0 } } }'
kourou subscribe iot-data sensors --filters '{ exists: "position" }' --scope out
kourou subscribe iot-data sensors --users all --volatile '{ clientId: "citizen-kane" }'
kourou subscribe iot-data sensors --display result._source.temperature
```

_See code: [src/commands/subscribe.ts](src/commands/subscribe.ts)_

## `kourou user:export`

Exports users to JSON.
Expand Down
6 changes: 3 additions & 3 deletions features/Document.feature
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Feature: Document Management
| body | { "name": "Sebastien", "city": "Cassis" } |
And I refresh the collection
When I run the command "document:search" with:
| arg | nyc-open-data | |
| arg | yellow-taxi | |
| flag | --query | { term: { city: "Saigon" } } |
| arg | nyc-open-data |
| arg | yellow-taxi |
| arg | { term: { city: "Saigon" } } |
Then I should match stdout with "Adrien"
And I should not match stdout with "Sebastien"
File renamed without changes.
5 changes: 3 additions & 2 deletions features/step_definitions/cli-steps.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
const _ = require('lodash')
const fs = require('fs')

const _ = require('lodash')
const { Then } = require('cucumber')

// this need to build the lib with "npm run build" first
const { execute } = require('../../lib/support/execute')

Then('I subscribe to {string}:{string}', async function (index, collection) {
this.props.executor = execute('./bin/run', 'subscribe', index, collection)
this.props.executor = execute('./bin/run', 'realtime:subscribe', index, collection)

// wait to connect to Kuzzle
await new Promise(resolve => setTimeout(resolve, 4000))
Expand Down
2 changes: 1 addition & 1 deletion src/commands/api-key/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ApiKeyCheck extends Kommand {
]

async runSafe() {
const { valid } = await this.sdk?.auth.checkToken(this.args.token)
const { valid } = await this.sdk.auth.checkToken(this.args.token)

if (valid) {
this.logOk('API key is still valid')
Expand Down
2 changes: 1 addition & 1 deletion src/commands/api-key/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ApiKeyCreate extends Kommand {
]

async runSafe() {
const apiKey = await this.sdk?.security.createApiKey(
const apiKey = await this.sdk.security.createApiKey(
this.args.user,
this.flags.description,
{
Expand Down
2 changes: 1 addition & 1 deletion src/commands/api-key/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ApiKeyDelete extends Kommand {
];

async runSafe() {
await this.sdk?.security.deleteApiKey(this.args.user, this.args.id)
await this.sdk.security.deleteApiKey(this.args.user, this.args.id)

this.logOk(`Successfully deleted API Key "${this.args.id}" of user "${this.args.user}"`)
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/api-key/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ApiKeySearch extends Kommand {
}
}

const result = await this.sdk?.security.searchApiKeys(
const result = await this.sdk.security.searchApiKeys(
this.args.user,
query,
{
Expand All @@ -43,6 +43,7 @@ class ApiKeySearch extends Kommand {
for (const { _id, _source } of result.hits) {
this.log(` - Key "${_id}"`)
this.log(` Description: ${_source.description}`)
this.log(` Fingerprint: ${_source.fingerprint}`)
this.log(` Expires at: ${_source.expiresAt}`)
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/collection/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export default class CollectionCreate extends Kommand {
async runSafe() {
const body = this.stdin ? this.stdin : this.args.body || '{}'

if (!await this.sdk?.index.exists(this.args.index)) {
await this.sdk?.index.create(this.args.index)
if (!await this.sdk.index.exists(this.args.index)) {
await this.sdk.index.create(this.args.index)

this.logInfo(`Index "${this.args.index}" created`)
}

await this.sdk?.collection.create(this.args.index, this.args.collection, this.parseJs(body))
await this.sdk.collection.create(this.args.index, this.args.collection, this.parseJs(body))

this.logOk(`Collection "${this.args.index}":"${this.args.collection}" created`)
}
Expand Down
4 changes: 2 additions & 2 deletions src/commands/collection/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ export default class CollectionExport extends Kommand {
query = this.fromEditor(query, { json: true })
}

const countAll = await this.sdk?.document.count(this.args.index, this.args.collection)
const count = await this.sdk?.document.count(this.args.index, this.args.collection, { query })
const countAll = await this.sdk.document.count(this.args.index, this.args.collection)
const count = await this.sdk.document.count(this.args.index, this.args.collection, { query })

this.logInfo(`Dumping ${count} of ${countAll} documents from collection "${this.args.index}:${this.args.collection}" in ${path} ...`)

Expand Down
17 changes: 7 additions & 10 deletions src/commands/document/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ export default class DocumentSearch extends Kommand {
static description = 'Searches for documents'

static examples = [
'kourou document:search iot sensors --query \'{ term: { name: "corona" } }\'',
'kourou document:search iot sensors \'{ term: { name: "corona" } }\'',
'kourou document:search iot sensors --editor',
]

static flags = {
query: flags.string({
description: 'Query in JS or JSON format.',
default: '{}'
}),
sort: flags.string({
description: 'Sort in JS or JSON format.',
default: '{}'
Expand All @@ -38,7 +34,8 @@ export default class DocumentSearch extends Kommand {

static args = [
{ name: 'index', description: 'Index name', required: true },
{ name: 'collection', description: 'Collection name', required: true }
{ name: 'collection', description: 'Collection name', required: true },
{ name: 'query', description: 'Query in JS or JSON format.' },
]

async runSafe() {
Expand All @@ -51,7 +48,7 @@ export default class DocumentSearch extends Kommand {
size: this.flags.size,
scroll: this.flags.scroll,
body: {
query: this.parseJs(this.flags.query),
query: this.parseJs(this.args.query || '{}'),
sort: this.parseJs(this.flags.sort)
}
}
Expand All @@ -61,13 +58,13 @@ export default class DocumentSearch extends Kommand {
request = this.fromEditor(request, { json: true })
}

const { result } = await this.sdk?.query(request)
const { result } = await this.sdk.query(request)

for (const document of result.hits) {
for (const document of result?.hits) {
this.logInfo(`Document ID: ${document._id}`)
this.log(`Content: ${JSON.stringify(document._source, null, 2)}`)
}

this.logOk(`${result.hits.length} documents fetched on a total of ${result.total}`)
this.logOk(`${result?.hits.length} documents fetched on a total of ${result?.total}`)
}
}
2 changes: 1 addition & 1 deletion src/commands/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default class Import extends Kommand {
const dump = JSON.parse(fs.readFileSync(file, 'utf8'))

const mapping = dump.content.mapping
await this.sdk?.security.updateUserMapping({ properties: mapping })
await this.sdk.security.updateUserMapping({ properties: mapping })

this.logOk('[users] collection mappings imported')
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/index/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class IndexExport extends Kommand {

fs.mkdirSync(exportPath, { recursive: true })

const { collections } = await this.sdk?.collection.list(this.args.index)
const { collections } = await this.sdk.collection.list(this.args.index)

for (const collection of collections) {
try {
Expand Down
4 changes: 2 additions & 2 deletions src/commands/profile/export.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from 'fs'
import fs from 'fs'
import path from 'path'

import { flags } from '@oclif/command'
Expand Down Expand Up @@ -46,7 +46,7 @@ export default class ProfileExport extends Kommand {
size: 100
}

let result = await this.sdk?.security.searchProfiles({}, options)
let result = await this.sdk.security.searchProfiles({}, options)

const profiles: any = {}

Expand Down
Loading