Search term
GraphQL Query API search capabilities
Hii Retail provides certain GraphQL Query APIs where the user can leverage the built in query and response capabilities GraphQL provides. See more about this here.
This section describes the advanced capabilities provided for free-text searching.
Free-text search often requires different things based on the application where it is available. Below you can find those advanced concepts described in more detail.
Query String Syntax
A query string uses specific syntax to parse and split the provided query string based on operators (AND, OR). The default operator is OR.
A query string can be a single word — bottle
or can
— or a phrase, surrounded by double quotes — "bright and bubbly"
— which searches for all the words in the phrase, in the same order.
A general recommendation is to NOT make heavy use of query string special syntax
For example, the wildcard and regular expressions should not be used unless it is absolutely necessary. A major reason is that an unfortunate implementation on the client side can result in heavy queries, slow response times, and bad user experience.
Invalid syntax in the searchTerm
will return an error, and it is important that this is handled by the search components.
.keyword
fields
It is also important to note the difference between a regular field name and the field name + a .keyword
suffix.
A text field like name
can be searched for individual words or phrases by using the field name alone - "bright and bubbly"
would give you a hit if the exact phrase is present anywhere in the name
field.
The name.keyword
field takes the same input and keeps it as one large string, or as a single keyword
. It is especially useful for structured content like email addresses, status codes, etc. - "bright and bubbly"
would only give you a hit if the phrase is the exact content of the name.keyword
field.
This allows you to get more performant hits on a specific phrase or word, if you know that it exists in this exact form in this particular field.
Example:
name: "Fizzy Drink 1"
will search for this exact combination of words and would get a hit if this combination was an exact match for the entirename
property, or as a part of thename
propertyname.keyword: "Fizzy Drink 1"
would NOT get a hit unless this was the exact phrase of thename
property.- The
.keyword
field is required if you need to use wildcard.
Supported Query Elements:
Reserved Characters
If you need to use any of the characters which function as operators in your query itself (and not as operators), then you should escape them with a leading backslash. The reserved characters are: +
-
=
&&
||
>
<
!
(
)
{
}
[
]
^
"
~
*
?
:
\
/
When using JSON for the request body, two preceding backslashes (\) are required. Failing to escape these special characters correctly could lead to a syntax error which prevents your query from running. < and > can’t be escaped at all. Examples:
\(1\+1\)\=2
- searches for (1+1)=2\\(1\\+1\\)\\=2
- the same query but when sent as JSON
Boolean Operators
The boolean operators which are supported are: + (indicates that a term must be present), - (indicates that a term must not be present), AND, OR, and NOT. Below are some examples:
bottle can +soda -fizzy
- states that:soda
must be present,fizzy
must not be present,bottle
andcan
are optional (their presence increases the relevance)((bottle AND soda) OR (can AND soda) OR soda) AND NOT fizzy
- it's the same query as the previous one written with the help of the boolean operators AND, OR and NOT (also can be written as &&, || and !)
Field Names
businessUnitId.keyword:1-1
- where thebusinessUnitId
field matches exactly the term1-1
- Note the use of
keyword
here. This allows an exact match to be found, but also increases performance of the query when an exact match is needed
- Note the use of
status: ACTIVE
- where thestatus
field containsACTIVE
name:(bottle OR flask)
- where thename
field containsbottle
orflask
description: "heavy duty fabric"
- where thedescription
field contains the exact phrase"heavy duty fabric"
assortment\*:(IN_ASSORTMENT, C)
- where any of the fieldsassortmentType
orassortmentTags
, etc. containsIN_ASSORTMENT
orC
- note how we need to escape the * with a backslash
_exists_:description
- where the fielddescription
has any non-null value
Search Multiple Fields
businessUnitId:AW001 AND status:ACTIVE
- where thebusinessUnitId
field containsAW001
andstatus
field containsACTIVE
.- The general form looks like this:
field1:query_term OR/AND field2:query_term | ...
.
- The general form looks like this:
Wildcards - USE WITH CARE!
p?nk XX*
- use?
to replace a single character, and*
to replace zero or more charactersfield:*
- a pure wildcard would match afield
with any value, including an empty value. It would not match if the field is missing or set with an explicit null valueWe do not support searching with a wildcard at the beginning of a word (eg. "*ing"). This has a heavy impact on performance thus it must not be used.
Regular Expressions - USE WITH CARE!
The supported regular expression syntax is explained in Regular expression syntax. Also, see some examples below:
name:/joh?n(ath[oa]n)/
- regular expression patterns can be embedded in the query string by wrapping them in forward-slashes.
Regular expressions like this one
/.*n/
are not supported because of performance reasons. Such queries must not be used.
Fuzziness
quikc~ brwn~ foks~3
- fuzzy queries can specify a maximum edit distance for characters in a word.- The edit distance is the minimum number of operations required to change one word into the other.
- The default edit distance is 2.
app*~1
- mixing fuzzy and wildcard operators is not supported.- When mixed, one of the operators is not applied. In this case, the fuzzy operator (~1) is not applied.
Proximity Searches
"fox quick"~5
- similar to fuzzy queries, but a proximity search allows us to specify a maximum edit distance of words in a phrase. A proximity query allows the specified words to be further apart or in a different order.
Ranges
Ranges can be specified for date, numeric, or string fields. Inclusive ranges are specified with square brackets [min TO max]
and exclusive ranges with curly brackets {min TO max}
. Examples:
validFrom:[2022-01-01 TO 2022-12-31]
- all days in 2022netContent:[1 TO 5]
- numbers 1..5assortmentTags:[A TO D]
- AssortmentTags between A and D, including A and DassortmentTags:{A TO D}
- AssortmentTags between A and D, excluding A and DnetContent:[10 TO *]
- numbers from 10 upwardsvalidTo:{* TO 2022-01-01}
- dates before 2022netContent:[1 TO 5}
- numbers from 1 up to but not including 5referencePriceConversionFactor:>1
- numbers greater than 1referencePriceConversionFactor:>=1.5
- numbers equal or greater than 1.5referencePriceConversionFactor:<1
- numbers less than 1referencePriceConversionFactor:<=0.9
- numbers equal or less than 0.9referencePriceConversionFactor:(>=1.1 AND <2)
- numbers equal or greater than 1.1 and less than 2netContent:[1 TO 5}
- curly and square brackets can be combinednetContent:>=10
,netContent:<=10
- you can use this syntax for ranges with one side unboundedage:(>=10 AND <20)
- you can join two clauses with an AND operator
Boosting
Use the boost operator ^ to make one term more relevant than another. The default boost value is 1, but can be any positive floating point number. Boosts between 0 and 1 reduce relevance. Below are some examples:
bottle^2 soda
- find all items about soda, but we are especially interested in soda bottles"soda bottle"^2
- boosts can also be applied to phrases(soda can)^4
- boosts can also be applied to groups
Grouping
(bottle OR can) AND soda
- multiple terms or clauses can be grouped together with parentheses to form sub-queriesstatus:(ACTIVE OR DISCONTINUED) name:(bright and bubbly)^2
- groups can be used to target a particular field, or to boost the result of a sub-query