Skip to content

Commit

Permalink
Support #32023 - Test partial search
Browse files Browse the repository at this point in the history
- Removed the "Contains word" option since depending on what's stored it can be confusing what's considered a word.
- "Starts with" will now not automatically lowercase the query.
- "Starts with" will include the "case_insensitive" as true.
- NotEquals should be using term not match, removed the "matchQuery" function.
- Removed all partial match/contains word tests and updated snapshots.
  • Loading branch information
brandonandre committed Oct 4, 2023
1 parent fba73fe commit abe68da
Show file tree
Hide file tree
Showing 19 changed files with 86 additions and 274 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ const OPERATOR_OPTIONS: FieldItems = [
key: "exactMatch",
label: "Exact Match"
},
{
key: "partialMatch",
label: "Partial Match"
},
{
key: "notEquals",
label: "Not Equals"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,30 +87,23 @@ exports[`QueryOperatorSelector component Snapshot Test 1`] = `
</div>
</EmotionCssPropInternal>
</Option>
<Option clearValue={[Function (anonymous)]} cx={[Function (anonymous)]} getStyles={[Function (anonymous)]} getValue={[Function (anonymous)]} hasValue={true} isMulti={false} isRtl={false} options={{...}} selectOption={[Function (anonymous)]} selectProps={{...}} setValue={[Function (anonymous)]} theme={{...}} innerProps={{...}} data={{...}} isDisabled={false} isSelected={false} label=\\"Partial Match\\" type=\\"option\\" value=\\"partialMatch\\" isFocused={false} innerRef={[undefined]}>
<Option clearValue={[Function (anonymous)]} cx={[Function (anonymous)]} getStyles={[Function (anonymous)]} getValue={[Function (anonymous)]} hasValue={true} isMulti={false} isRtl={false} options={{...}} selectOption={[Function (anonymous)]} selectProps={{...}} setValue={[Function (anonymous)]} theme={{...}} innerProps={{...}} data={{...}} isDisabled={false} isSelected={false} label=\\"Not Equals\\" type=\\"option\\" value=\\"notEquals\\" isFocused={false} innerRef={[undefined]}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-1\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-1\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
Partial Match
</div>
</EmotionCssPropInternal>
</Option>
<Option clearValue={[Function (anonymous)]} cx={[Function (anonymous)]} getStyles={[Function (anonymous)]} getValue={[Function (anonymous)]} hasValue={true} isMulti={false} isRtl={false} options={{...}} selectOption={[Function (anonymous)]} selectProps={{...}} setValue={[Function (anonymous)]} theme={{...}} innerProps={{...}} data={{...}} isDisabled={false} isSelected={false} label=\\"Not Equals\\" type=\\"option\\" value=\\"notEquals\\" isFocused={false} innerRef={[undefined]}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-2\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-2\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
Not Equals
</div>
</EmotionCssPropInternal>
</Option>
<Option clearValue={[Function (anonymous)]} cx={[Function (anonymous)]} getStyles={[Function (anonymous)]} getValue={[Function (anonymous)]} hasValue={true} isMulti={false} isRtl={false} options={{...}} selectOption={[Function (anonymous)]} selectProps={{...}} setValue={[Function (anonymous)]} theme={{...}} innerProps={{...}} data={{...}} isDisabled={false} isSelected={false} label=\\"Empty\\" type=\\"option\\" value=\\"empty\\" isFocused={false} innerRef={[undefined]}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-3\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-3\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-2\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-2\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
Empty
</div>
</EmotionCssPropInternal>
</Option>
<Option clearValue={[Function (anonymous)]} cx={[Function (anonymous)]} getStyles={[Function (anonymous)]} getValue={[Function (anonymous)]} hasValue={true} isMulti={false} isRtl={false} options={{...}} selectOption={[Function (anonymous)]} selectProps={{...}} setValue={[Function (anonymous)]} theme={{...}} innerProps={{...}} data={{...}} isDisabled={false} isSelected={false} label=\\"Not Empty\\" type=\\"option\\" value=\\"notEmpty\\" isFocused={false} innerRef={[undefined]}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-4\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-4\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
<EmotionCssPropInternal css={{...}} className=\\"\\" aria-disabled={false} id=\\"react-select-2-option-3\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1} __EMOTION_TYPE_PLEASE_DO_NOT_USE__=\\"div\\" __EMOTION_LABEL_PLEASE_DO_NOT_USE__=\\"Option\\">
<div className=\\" css-yt9ioa-option\\" aria-disabled={false} id=\\"react-select-2-option-3\\" onClick={[Function (anonymous)]} onMouseMove={[Function (anonymous)]} onMouseOver={[Function (anonymous)]} tabIndex={-1}>
Not Empty
</div>
</EmotionCssPropInternal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,15 +403,6 @@ export function wildcardQuery(fieldName: string, matchValue: any, keywordSupport
};
}

// Query used for partial matches (contains word).
export function matchQuery(fieldName: string, matchValue: any): any {
return {
match: {
[fieldName]: matchValue
}
};
}

// Query used to see if the field exists.
export function existsQuery(fieldName: string): any {
return {
Expand Down Expand Up @@ -442,11 +433,6 @@ export function prefixQuery(
return {};
}

// Lowercase the matchValue here, if it's a string.
if (typeof matchValue === "string") {
matchValue = matchValue.toLowerCase();
}

return parentType
? {
nested: {
Expand All @@ -456,8 +442,10 @@ export function prefixQuery(
must: [
{
prefix: {
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]:
matchValue
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: {
value: matchValue,
case_insensitive: true
}
}
},
includedTypeQuery(parentType)
Expand All @@ -468,7 +456,10 @@ export function prefixQuery(
}
: {
prefix: {
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: matchValue
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: {
value: matchValue,
case_insensitive: true
}
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,15 +415,6 @@ export function wildcardQuery(fieldName: string, matchValue: any, keywordSupport
};
}

// Query used for partial matches (contains word).
export function matchQuery(fieldName: string, matchValue: any): any {
return {
match: {
[fieldName]: matchValue
}
};
}

// Query used to see if the field exists.
export function existsQuery(fieldName: string): any {
return {
Expand Down Expand Up @@ -454,11 +445,6 @@ export function prefixQuery(
return {};
}

// Lowercase the matchValue here, if it's a string.
if (typeof matchValue === "string") {
matchValue = matchValue.toLowerCase();
}

return parentType
? {
nested: {
Expand All @@ -468,8 +454,10 @@ export function prefixQuery(
must: [
{
prefix: {
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]:
matchValue
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: {
value: matchValue,
case_insensitive: true
}
}
},
includedTypeQuery(parentType)
Expand All @@ -480,7 +468,10 @@ export function prefixQuery(
}
: {
prefix: {
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: matchValue
[optimizedPrefix ? fieldName + ".prefix" : keywordSupport ? fieldName + ".keyword" : fieldName]: {
value: matchValue,
case_insensitive: true
}
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
applySourceFiltering,
includedTypeQuery,
termQuery,
matchQuery,
existsQuery,
rangeQuery,
prefixQuery,
Expand Down Expand Up @@ -275,10 +274,6 @@ describe("QueryBuilderElasticSearchExport functionality", () => {
expect(wildcardQuery("fieldTest", "valueToMatch", true)).toMatchSnapshot();
});

test("matchQuery", async () => {
expect(matchQuery("fieldTest", "valueToMatch")).toMatchSnapshot();
});

test("existsQuery", async () => {
expect(existsQuery("fieldTest")).toMatchSnapshot();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,32 @@ Object {
exports[`QueryBuilderElasticSearchExport functionality Partial matching query helper functions prefixQuery attribute (not optimized) 1`] = `
Object {
"prefix": Object {
"data.attribute.materialSampleName": "searchvalue",
"data.attribute.materialSampleName": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
}
`;

exports[`QueryBuilderElasticSearchExport functionality Partial matching query helper functions prefixQuery attribute (not optimized, keyword support) 1`] = `
Object {
"prefix": Object {
"data.attribute.materialSampleName.keyword": "searchvalue",
"data.attribute.materialSampleName.keyword": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
}
`;

exports[`QueryBuilderElasticSearchExport functionality Partial matching query helper functions prefixQuery attribute (optimized) 1`] = `
Object {
"prefix": Object {
"data.attribute.materialSampleName.prefix": "searchvalue",
"data.attribute.materialSampleName.prefix": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
}
`;
Expand All @@ -69,7 +78,10 @@ Object {
"must": Array [
Object {
"prefix": Object {
"included.attributes.dwcRecordNumber": "searchvalue",
"included.attributes.dwcRecordNumber": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
},
Object {
Expand All @@ -93,7 +105,10 @@ Object {
"must": Array [
Object {
"prefix": Object {
"included.attributes.dwcRecordNumber.keyword": "searchvalue",
"included.attributes.dwcRecordNumber.keyword": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
},
Object {
Expand All @@ -117,7 +132,10 @@ Object {
"must": Array [
Object {
"prefix": Object {
"included.attributes.dwcRecordNumber.prefix": "searchvalue",
"included.attributes.dwcRecordNumber.prefix": Object {
"case_insensitive": true,
"value": "searchValue",
},
},
},
Object {
Expand Down Expand Up @@ -180,14 +198,6 @@ Object {
}
`;

exports[`QueryBuilderElasticSearchExport functionality Query helper functions matchQuery 1`] = `
Object {
"match": Object {
"fieldTest": "valueToMatch",
},
}
`;

exports[`QueryBuilderElasticSearchExport functionality Query helper functions rangeQuery 1`] = `
Object {
"range": Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ export default function QueryRowFieldExtensionSearch({
const operatorOptions = [
"exactMatch",
"wildcard",
"partialMatch",
"startsWith",
"notEquals",
"empty",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ export default function QueryRowManagedAttributeSearch({
return [
"exactMatch",
"wildcard",
"partialMatch",
"startsWith",
"notEquals",
"empty",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";
import {
includedTypeQuery,
matchQuery,
termQuery,
existsQuery,
prefixQuery,
Expand Down Expand Up @@ -75,13 +74,9 @@ export function transformTextSearchToDSL({
keywordMultiFieldSupport
} = fieldInfo;

// Is the "Exact" option selected? (Or if auto suggestions are being used.)
const isExactMatch: boolean = distinctTerm || operation === "exactMatch";

switch (operation) {
// Equals match type.
case "equals":
case "partialMatch":
case "exactMatch":
// Autocompletion expects to use the full text search.
return parentType
Expand All @@ -91,18 +86,14 @@ export function transformTextSearchToDSL({
query: {
bool: {
must: [
isExactMatch
? termQuery(fieldPath, value, keywordMultiFieldSupport)
: matchQuery(fieldPath, value),
termQuery(fieldPath, value, keywordMultiFieldSupport),
includedTypeQuery(parentType)
]
}
}
}
}
: isExactMatch
? termQuery(fieldPath, value, keywordMultiFieldSupport)
: matchQuery(fieldPath, value);
: termQuery(fieldPath, value, keywordMultiFieldSupport)

// Wild card search
case "wildcard":
Expand Down Expand Up @@ -146,13 +137,11 @@ export function transformTextSearchToDSL({
path: "included",
query: {
bool: {
must_not: isExactMatch
? termQuery(
must_not: termQuery(
fieldPath,
value,
keywordMultiFieldSupport
)
: matchQuery(fieldPath, value),
),
must: includedTypeQuery(parentType)
}
}
Expand Down Expand Up @@ -188,9 +177,7 @@ export function transformTextSearchToDSL({
should: [
{
bool: {
must_not: isExactMatch
? termQuery(fieldPath, value, keywordMultiFieldSupport)
: matchQuery(fieldPath, value)
must_not: termQuery(fieldPath, value, keywordMultiFieldSupport)
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,35 +239,6 @@ describe("QueryBuilderDateSearch", () => {
});
});

describe("Partial Match operation", () => {
test("With relationship as field", async () => {
expect(
transformDateSearchToDSL({
operation: "partialMatch",
value: "1998-05-19",
fieldInfo: {
parentType: "collection",
parentName: "collection"
} as any,
fieldPath: "includes.name",
queryType: "partialMatch"
})
).toMatchSnapshot();
});

test("Normal field", async () => {
expect(
transformDateSearchToDSL({
operation: "partialMatch",
value: "1998-05-19",
fieldInfo: {} as any,
fieldPath: "data.attributes.dateField",
queryType: "partialMatch"
})
).toMatchSnapshot();
});
});

describe("Exact Match operation", () => {
test("With relationship as field", async () => {
expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ describe("QueryBuilderManagedAttributeSearch", () => {
const operators = [
"exactMatch",
"wildcard",
"partialMatch",
"startsWith",
"notEquals",
"empty",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ describe("QueryBuilderManagedAttributeSearch", () => {
operators: [
"exactMatch",
"wildcard",
"partialMatch",
"startsWith",
"notEquals",
"empty",
Expand Down
Loading

0 comments on commit abe68da

Please sign in to comment.