Node.js client library for constructing OpenSearch query.
npm install @victoriabros/opq
Constructing queries for OpenSearch index has never been this simplified. opq provides queries that can be used to construct simple, complex and custom JSON queries for OpenSearch.
See example: match.js
const { pipeline, query } = require('@victoriabros/opq');
const pipelineQ = pipeline(
query.match('customer_first_name', 'Sonya'),
query.withQuery(),
);
console.log(pipelineQ());
$ node match.js
{ query: { match: { customer_first_name: [Object] } } }
Here's a more complete query based on Paginate results documentation from OpenSeach using several query from opq and pretty printing the output.
See example: paginate.js
const { pipeline, query } = require('@victoriabros/opq');
const paginateQ = pipeline(
query.match('play_name', 'Hamlet'),
query.withPaginate(0, 3),
query.withSort([
{
'speech_number': 'asc'
},
{
'_id': 'asc'
}
]),
query.withQuery(),
query.withPrettyPrint(),
);
paginateQ();
$ node paginate.js
{
"query": {
"match": {
"play_name": {
"query": "Hamlet"
}
},
"from": 0,
"size": 3,
"sort": [
{
"speech_number": "asc"
},
{
"_id": "asc"
}
]
}
}
More snippets can be found in the examples directory
Opq exports query.*
which has several functions that can be used within pipeline
.
const { query } = require('@victoriabros/opq');
This allows including the match_phrase_prefix
field which searches for documents matching the provided phrase.
See example: matchprefix.js
This allows including the match_bool_prefix
field which analyzes the provided search string and creates a Boolean query.
See example: matchbool.js
This allows including the match
field to perform full-text search.
See example: match.js
This allows including the multimatch
field to search multiple fields in the index. By default, fields
will be *
which searches the fields specified in the index query.
See example: multimatch.js
This allows including the match_all
field that queries the entire index.
This allows including the term
field.
See example: array.js#L9
This allows including the terms
field.
See example: array.js#L10
checks if a field with a name exists.
const { query } = require('@victoriabros/opq');
const withExists = query.exists({
'name': 'created_at',
});
This allows to search for a range of given values in a field.
const { query } = require('@victoriabros/opq');
const withRange = query.range('created_at', {
'gte': '2023-04-01',
'lte': '2024-04-08'
});
This allows include the should
field which is equivalent to logical or
operator.
See example: match.js#L9
This allows include the must
field which is equivalent to logical and
operator.
See example: siblings.js#L10
This allows include the must_not
field which is equivalent to logical not
operator.
See example: array.js#L19
This allows including the bool
field that can be combined with withMustNot
, withMust
, withShould
and withFilter
.
See example: siblings.js#L11
This allows including the query
field.
See example: array.js#L23
This allows including the filter
field.
See example: filter.js
This allows including the from
and size
fields. The from
field is computed based on offset
and limit
provided.
See example: paginate.js
This allows including the highlight
field with option to replace the preTags
, postTags
and additional highlighting options.
See example: highlight.js
const { query } = require('@victoriabros/opq');
query.withHighlight([
{ 'email': {} },
{ 'username': {} }
], {
'pre_tags': ['<em>'],
'post_tags': ['</em>'],
'order': 'score',
'number_of_fragments': 0,
});
This allows including the sort
field with option to add flexible attributes.
See example: paginate.js#L8
This allows including the _source
field.
See example: array.js#L24
This allows providing constant value with custom key.
See example: siblings.js#L8
This allows placing sub-queries within an array.
See example: array.js
This allows placing adjacent queries or sub-queries.
See example: siblings.js
By default, prettyprint outputs composed query to console. You may change the default logger.
See example: paginate.js#L17
const { query } = require('@victoriabros/opq');
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.Console({ level: 'warn' }),
new winston.transports.File({ filename: 'combined.log' })
],
});
query.withPrettyPrint({}, logger.info);
This allows including the script_score
to change the scoring function of queried documents.
const { query } = require('@victoriabros/opq');
query.withScriptScore(
query.match('author', 'Dave')(),
{
source: `
_score * doc[params.field].value
`,
params: {
'field': 'multiplier'
}
}
);
{
'script_score': {
'query': {
'match': {
'author': {
'query': 'Dave',
. . .
}
}
},
'script': {
lang: 'painless',
source: '\n _score * doc[params.field].value\n ',
params: { 'field': 'multiplier' }
}
}
}
You can execute custom queries in addition to the built-in queries using pipeline
.
See example: custom.js
const { pipeline } = require('@victoriabros/opq');
const customFunction = (text) => {
return (baseQuery) => ({
...baseQuery,
'custom_attribute': text
});
};
const pipelineQ = pipeline(
query.match('fruit_name', 'Orange'),
query.withQuery(),
customFunction('custom_value'),
query.withPrettyPrint(),
);
pipelineQ();
$ node sample-custom.js
{
"query": {
"match": {
"fruit_name": {
"query": "Orange",
"operator": "OR",
"max_expansions": 30,
"boost": 1
}
}
},
"custom_attribute": "custom_value"
}
Connection to OpenSearch can be initiated using newClient
. It requires at minimum host
, username
and password
but you can provide additional configuration to fine-tune the performance such as circuit breaking.
See example: client.js
const { newClient } = require('@victoriabros/opq');
const client = newClient({
// required
host: 'localhost:9200',
username: 'admin',
password: 'admin',
// optional
enableLongNumeralSupport: true,
memoryCircuitBreakerEnabled: true,
memoryCircuitBreakerMaxPercent: 0.8,
});
You can validate configuration credentials using createCredentials
.
const { createCredentials } = require('@victoriabros/opq');
console.log(createCredentials({
// required
host: 'localhost:9200',
username: 'admin',
password: 'admin',
// optional
protocol: 'http' // defaults to https
}));
debug a tiny JavaScript debugging utility tool is used for client error and info output. The debug output can be toggled by prefix node command with DEBUG=*
for the whole module or DEBUG=opensearch:opq
for opq only output.
DEBUG=* node examples/client.js