dsl-builder-test
Version:
OpenSearch Query Builder - Extract from OpenSearch Dashboards
115 lines (114 loc) • 4.45 kB
JavaScript
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { get, isPlainObject } from 'lodash';
export const isPhraseFilter = (filter) => {
const isMatchPhraseQuery = filter && filter.query && filter.query.match_phrase;
const isDeprecatedMatchPhraseQuery = filter &&
filter.query &&
filter.query.match &&
Object.values(filter.query.match).find((params) => params.type === 'phrase');
return Boolean(isMatchPhraseQuery || isDeprecatedMatchPhraseQuery);
};
export const isScriptedPhraseFilter = (filter) => Boolean(get(filter, 'script.script.params.value'));
export const getPhraseFilterField = (filter) => {
const queryConfig = filter.query.match_phrase || filter.query.match;
return Object.keys(queryConfig)[0];
};
export const getPhraseFilterValue = (filter) => {
const queryConfig = filter.query.match_phrase || filter.query.match;
const queryValue = Object.values(queryConfig)[0];
return isPlainObject(queryValue) ? queryValue.query : queryValue;
};
export const buildPhraseFilter = (field, value, indexPattern) => {
const convertedValue = getConvertedValueForField(field, value);
if (field.scripted) {
return {
meta: { index: indexPattern.id, field: field.name },
script: getPhraseScript(field, value),
};
}
else {
return {
meta: { index: indexPattern.id },
query: {
match_phrase: {
[field.name]: convertedValue,
},
},
};
}
};
export const getPhraseScript = (field, value) => {
const convertedValue = getConvertedValueForField(field, value);
const script = buildInlineScriptForPhraseFilter(field);
return {
script: {
source: script,
lang: field.lang,
params: {
value: convertedValue,
},
},
};
};
// See https://github.com/elastic/elasticsearch/issues/20941 and https://github.com/elastic/kibana/issues/8677
// and https://github.com/elastic/elasticsearch/pull/22201
// for the reason behind this change. Aggs now return boolean buckets with a key of 1 or 0.
export const getConvertedValueForField = (field, value) => {
if (typeof value !== 'boolean' && field.type === 'boolean') {
if ([1, 'true'].includes(value)) {
return true;
}
else if ([0, 'false'].includes(value)) {
return false;
}
else {
throw new Error(`${value} is not a valid boolean value for boolean field ${field.name}`);
}
}
return value;
};
/**
* Takes a scripted field and returns an inline script appropriate for use in a script query.
* Handles lucene expression and Painless scripts. Other langs aren't guaranteed to generate valid
* scripts.
*
* @param {object} scriptedField A Field object representing a scripted field
* @returns {string} The inline script string
*/
export const buildInlineScriptForPhraseFilter = (scriptedField) => {
// We must wrap painless scripts in a lambda in case they're more than a simple expression
if (scriptedField.lang === 'painless') {
return (`boolean compare(Supplier s, def v) {return s.get() == v;}` +
`compare(() -> { ${scriptedField.script} }, params.value);`);
}
else {
return `(${scriptedField.script}) == value`;
}
};