diff --git a/common/constants.ts b/common/constants.ts
index b8c51b85..76435d0b 100644
--- a/common/constants.ts
+++ b/common/constants.ts
@@ -185,6 +185,7 @@ export const NORMALIZATION_PROCESSOR_LINK =
'https://opensearch.org/docs/latest/search-plugins/search-pipelines/normalization-processor/';
export const GITHUB_FEEDBACK_LINK =
'https://github.com/opensearch-project/dashboards-flow-framework/issues/new/choose';
+export const JSONPATH_DOCS_LINK = 'https://www.npmjs.com/package/jsonpath';
/**
* Text chunking algorithm constants
diff --git a/public/general_components/jsonpath_examples_table.tsx b/public/general_components/jsonpath_examples_table.tsx
index b05c9eb6..4b40c3b0 100644
--- a/public/general_components/jsonpath_examples_table.tsx
+++ b/public/general_components/jsonpath_examples_table.tsx
@@ -11,7 +11,10 @@ import {
EuiText,
EuiFlexGroup,
EuiFlexItem,
+ EuiLink,
+ EuiSpacer,
} from '@elastic/eui';
+import { JSONPATH_DOCS_LINK } from '../../common';
interface JsonPathExamplesTableProps {
headerText?: string;
@@ -25,9 +28,55 @@ type JSONPathExample = {
const examples = [
{
- expression: '$.data',
- meaning: 'The entire input',
- example: '$.data',
+ expression: '$',
+ meaning: 'The root object / element',
+ example: '$.my_field',
+ },
+ {
+ expression: '.',
+ meaning: 'Child member operator',
+ example: 'my_field.my_sub_field',
+ },
+ {
+ expression: '..',
+ meaning:
+ 'Recursive descendant operator, to specify an object field in an array of objects',
+ example: '$..my_field',
+ },
+ {
+ expression: '*',
+ meaning: 'Wildcard matching all objects',
+ example: 'my_array.*',
+ },
+ {
+ expression: '[]',
+ meaning: 'Subscript operator',
+ example: 'my_array[0]',
+ },
+ {
+ expression: '[,]',
+ meaning: 'Union operator for alternate names or array indices as a set',
+ example: 'my_array[0,1]',
+ },
+ {
+ expression: '[start:end:step]',
+ meaning: 'Array slice operator borrowed from ES4 / Python',
+ example: 'my_array[0:5]',
+ },
+ {
+ expression: '@',
+ meaning: 'The current object / element in an array',
+ example: 'my_array[?(@.price<10)]',
+ },
+ {
+ expression: '()',
+ meaning: 'Script expression via static evaluation',
+ example: 'my_array[?(@.price<10)]',
+ },
+ {
+ expression: '?()',
+ meaning: 'Applies a filter (script) expression via static evaluation',
+ example: 'my_array[?(@.price<10)]',
},
] as JSONPathExample[];
@@ -61,7 +110,7 @@ const columns = [
*/
export function JsonPathExamplesTable(props: JsonPathExamplesTableProps) {
return (
-
+
{!isEmpty(props.headerText) && (
@@ -77,6 +126,12 @@ export function JsonPathExamplesTable(props: JsonPathExamplesTableProps) {
hasActions={false}
/>
+
+
+
+ More examples & documentation
+
+
);
diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/ml_processor_inputs.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/ml_processor_inputs.tsx
index 995f39f6..c9286dcf 100644
--- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/ml_processor_inputs.tsx
+++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/ml_processor_inputs.tsx
@@ -194,19 +194,11 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) {
@@ -222,13 +214,23 @@ export function MLProcessorInputs(props: MLProcessorInputsProps) {
isDataFetchingAvailable={isInputPreviewAvailable}
/>
-
+
{`Outputs`}
+
+
+
(false);
+ // JSONPath details popover state
+ const [popoverOpen, setPopoverOpen] = useState(false);
+
// validation state utilizing the model interface, if applicable. undefined if
// there is no model interface and/or no source input
const [isValid, setIsValid] = useState(undefined);
@@ -306,27 +312,39 @@ export function ConfigureExpressionModal(props: ConfigureExpressionModalProps) {
-
+
-
+
{`Expression`}
-
+ setPopoverOpen(false)}
+ button={
+ setPopoverOpen(!popoverOpen)}
+ >
+ Learn more
+
+ }
+ >
+
+
@@ -339,18 +357,29 @@ export function ConfigureExpressionModal(props: ConfigureExpressionModalProps) {
-
+
+
+
+
+ {props.context ===
+ PROCESSOR_CONTEXT.SEARCH_RESPONSE && (
+
+
+ {`Tip: to include data from the the original query request, prefix your expression with "${REQUEST_PREFIX}" - for example, "_request.query.match.my_field"`}
+
+
+ )}
+
{props.modelInputFieldName}
-
diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx
index a640a1ed..882c62fb 100644
--- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx
+++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx
@@ -21,7 +21,7 @@ import {
EuiSmallButtonEmpty,
EuiSpacer,
EuiSmallButtonIcon,
- EuiIconTip,
+ EuiPopover,
} from '@elastic/eui';
import {
customStringify,
@@ -59,7 +59,10 @@ import {
useAppDispatch,
} from '../../../../../../store';
import { getCore } from '../../../../../../services';
-import { QueryParamsList } from '../../../../../../general_components';
+import {
+ JsonPathExamplesTable,
+ QueryParamsList,
+} from '../../../../../../general_components';
interface ConfigureMultiExpressionModalProps {
uiConfig: WorkflowConfig;
@@ -143,6 +146,9 @@ export function ConfigureMultiExpressionModal(
// button updating state
const [isUpdating, setIsUpdating] = useState(false);
+ // JSONPath details popover state
+ const [popoverOpen, setPopoverOpen] = useState(false);
+
// source input / transformed input state
const [sourceInput, setSourceInput] = useState('{}');
const [transformedInput, setTransformedInput] = useState('{}');
@@ -278,18 +284,39 @@ export function ConfigureMultiExpressionModal(
-
+
{`Expression`}
-
+ setPopoverOpen(false)}
+ button={
+ setPopoverOpen(!popoverOpen)}
+ >
+ Learn more
+
+ }
+ >
+
+
diff --git a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx
index dc0ab268..eb5612dc 100644
--- a/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx
+++ b/public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx
@@ -65,7 +65,10 @@ import {
useAppDispatch,
} from '../../../../../../store';
import { getCore } from '../../../../../../services';
-import { QueryParamsList } from '../../../../../../general_components';
+import {
+ JsonPathExamplesTable,
+ QueryParamsList,
+} from '../../../../../../general_components';
interface ConfigureTemplateModalProps {
uiConfig: WorkflowConfig;
@@ -166,6 +169,9 @@ export function ConfigureTemplateModal(props: ConfigureTemplateModalProps) {
// popover states
const [presetsPopoverOpen, setPresetsPopoverOpen] = useState(false);
+ const [jsonPathPopoverOpen, setJsonPathPopoverOpen] = useState(
+ false
+ );
// source input / transformed input state
const [sourceInput, setSourceInput] = useState('{}');
@@ -448,9 +454,47 @@ export function ConfigureTemplateModal(props: ConfigureTemplateModalProps) {
-
- {`Expression`}
-
+
+
+
+ {`Expression`}
+
+
+
+
+ setJsonPathPopoverOpen(false)
+ }
+ button={
+
+ setJsonPathPopoverOpen(
+ !jsonPathPopoverOpen
+ )
+ }
+ >
+ Learn more
+
+ }
+ >
+
+
+
+
diff --git a/public/utils/config_to_schema_utils.ts b/public/utils/config_to_schema_utils.ts
index 3d3b3c98..8bcfb007 100644
--- a/public/utils/config_to_schema_utils.ts
+++ b/public/utils/config_to_schema_utils.ts
@@ -177,7 +177,7 @@ export function getFieldSchema(
)
.test(
'jsonArray',
- `Too large. Exceeds OpenSearch Dashboards limit of ${MAX_BYTES} bytes.`,
+ `The data size exceeds the limit of ${MAX_BYTES} bytes`,
(value) => {
try {
// @ts-ignore