Table of Contents

Queries

A query is a request for data from an index. It specifies criteria that the data must meet to be included in the search results. Queries are essential in search engines and databases to retrieve specific information based on various conditions.

An example of a query could be ‘Return all active products with a price below 100’ or ‘Return all users who live in Denmark’.

Creating a Query

To create a query, follow these steps:

  1. Navigate to Settings > Repositories and enter the repository you wish to add a query to
  2. In the Queries section, click Manage
  3. Click New Query
  4. Provide a name and select the Source index you want to query
    • A source index in e-commerce queries refers to a specific data repository or database from which the query retrieves information. It is essentially the origin of the data that is being queried. The source index serves as the foundation for data extraction. It contains the raw data that the query will process, filter, or analyze.
  5. Click Save and close

You have now created an empty query you can access: Queries_01

Before we move on, let's have a look at the anatomy of the query that we've just created. We can see that the query has three sections:

  • Parameters: Allow the query to accept dynamic input values, making it flexible
  • Expressions: Define the criteria to filter data
  • Sortings: Organize the search results based on specified fields

We'll now delve deeper into how these work, starting with:

Expressions

The core of a query lies in the set of expressions which dictates the result it returns. You can think of an unmodified or 'empty' query as one that returns everything in the index. Each expression you add, acts as a filter, narrowing down the results to match your specific needs. In other words, an expression limits the returned data to exactly what you want to see.

The anatomy of an expression is this:

  • Field: A category or type of information about a product e.g. Price or Name
  • Operator: Specifies the kind of comparison or condition you want to apply, e.g. are values equal, greater than, or less than others
  • Type: Determines the kind of test value the query should return e.g. a fixed number, a dynamic value, a user input, or a specific search term

Expressions_01

In the example below, we're testing if a product is marked as Active and whether its Price is less than or equal to 0. If a product meets both these conditions, it will be included in the results of the query. Queries_02

Expression Groups

Expressions can be grouped together to refine your search criteria. There are two main types of groups:

  • AND-groups: All expressions inside the group must be true for a product to be included in the results
    • Example: Brand = "Apple" AND Rating >= 4.5
  • OR-groups: At least one of the expressions inside the group must be true for a product to be included in the results
    • Example: Color = "Red" OR Color = "Blue"

To create a group for Expressions:

  1. In your query, navigate to the Expressions section and click Manage
  2. Click New group
  3. Choose whether the group should be an 'AND-group' or an 'OR-group'
  4. If needed, check the Negate option
    • The negation returns all products that do not match the expressions in the group, in a group with multiple expressions, each expression is evaluated on its own first and then negated

Expressions_02

Example: Expression

Let's return to our example query that checks if a product is marked as Active and whether its Price is less than or equal to 0. Remember, it consists of two expressions in an AND-group:

  • First Expression
    • Field: Active
    • Operator: Equal
    • Value: True
  • Second Expression
    • Field: Price
    • Operator: LessThanOrEqual
    • Value: 0

Too see this simple expression in a concrete example, let's see what it does on this dummy product index:

ProductID Name Active Price
1 Laptop Active 1200
2 Headphones Not Active 150
3 Mouse Active 25
4 Keyboard Active 0
5 Monitor Not Active 300

In this table, the columns 'ProductID', 'Name', 'Active', and 'Price' are referred to as fields. The specific values in the table, such as '1', 'Laptop', 'Active', and '1200', are called terms.

Step-by-Step Query Execution:

  • First expression: Retrieve products with Status = Active
    • Matching products: ProductID 1, ProductID 3, ProductID 4
  • Second Expression: From the matching products, retrieve those with Price <= 0
    • Matching products: ProductID 4 (since only ProductID 4 has a price of 0)

So, the query only returns ProductID 4 (keyboard), since its the only product that meets both expressions. If we had checked the negate button, all the products except ProductID 4 would have been returned.

Operators

When creating expressions, choosing an operator is mandatory to specify the kind of comparison or condition you want to apply.

The operators available to you depend on the type of field you select. This ensures that you only see and select operators that are relevant to your chosen field, making the process more intuitive. It also limits logical inconsistencies and provides a better understanding of the field-specific logic where e.g. operators like Contains or Equal serves Text fields better than numeric comparison operators.

Let's look at the operators in our example expression:

  • Price (Numeric Field)
    • Available Operators: Between, Equal, GreaterThan, GreaterThanOrEqual, In, IsEmpty, LessThan, LessThanOrEqual
    • Usage in example expression:
      • Expression: Price <= 0
      • Field: Price
      • Operator: LessThanOrEqual
  • Active (Boolean Field)
    • Available Operators: Equal, In
    • Usage in example expression:
      • Expression: Active = Active
      • Field: Active
      • Operator: Equal

An overview of some operators that may not be self-explanatory:

Operator Description Example
Equal Checks if the field value is equal to the test value. If the test value is an array, this operator works like the MatchAll operator Find products with a status of 'Active': Status Equal 'Active'
MatchAny Checks if the field contains any of the test values Find products in either 'Electronics', 'Books', or 'Clothing' categories: Category MatchAny ['Electronics', 'Books', 'Clothing']
MatchAll Checks if the field contains all the test values Find products that have all tags 'New', 'OnSale', and 'Featured': Tags MatchAll ['New', 'OnSale', 'Featured']
In Works like MatchAny but only accepts arrays as the test value, whereas MatchAny also accepts non-arrays as test values Find users with IDs 101, 102, or 103: UserID In [101, 102, 103]
Contains Looks for a partial match between the field value and the test value, matching values from their beginning (e.g., using [term]) Find products whose names start with 'Smart': Name Contains 'Smart'
ContainsExtended Looks for a partial match between the field value and the test values, matching values anywhere (e.g., using [term]) This comes with a significant performance and memory overhead. Find products whose descriptions contain 'wireless': Description ContainsExtended 'wireless'
IsEmpty Checks if a field is empty or not set Find records where the Email field is empty: Email IsEmpty

Types & Test Values

The Type in an expression determines the kind of test value you're working with.

A Test Value is the specific data or input that an expression evaluates against to determine if a condition is met. For example, in the expression Category = 'Electronics', the test value is 'Electronics', which the expression uses to check if the Category of an item is 'Electronics'.

The following Types are available:

Type Description Use cases Example
Constant A fixed unchanging value that is defined in a query. It is a specific value that does not vary during the execution of the query, regardless of the context or user interactions Filtering: When you want to filter data based on a fixed criterion.
Thresholds: Setting limits or boundaries that do not vary
Find all products priced below $100 with a filter, the query is 'Price < 100'. The value '100' is a constant and is used to compare each product's price
Macro A dynamic placeholder that gets replaced with actual values derived from the current context at runtime. Macros are useful for inserting context-specific data into a query, making the query adaptable to different users or situations User-specific Data: Tailoring results to the current user.
Session-specific Data: Adjusting queries based on the session information
Retrieve records associated with the currently logged-in user, the query is 'UserID = CurrentUserID'. 'CurrentUserID' is a macro that gets replaced with the actual user ID at runtime
Parameter A dynamic value passed to the query from an external source, such as through a search field, a facet, or other user inputs. We'll delver deeper into parameters here Dynamic Filtering: Allowing users to refine search results based on their input Users should be able to filter products by category, the query is 'Category = SelectedCategory'. 'SelectedCategory' is a parameter that gets its value from the user's selection in e.g. a dropdown menu or search field, and will be dynamically replaced with the actual category chosen by the user at runtime
Term A static value existing in the field being queried. It's akin to a word or phrase someone enters into a search box Keyword Search: Finding records that contain a specific word or phrase Find products that mention "laptop" in their description, the query is 'Description Contains "laptop"'. "Laptop" is a term used within the 'Description' field. The query checks for records where the description includes this specific word

When selecting a Type, specific options for that individual type will appear. To define the specific types:

  • Constant: Select an available data type and enter a value
  • Macro: Select one of the context-specific values available
  • Parameter: Select a parameter - see later section
  • Term: Select the terms existing in the Field you've selected
Tip

Matching null values

Lucene, the software library used to build repositories, does not index Null values or empty strings at all, which means that you cannot easily isolate index entries without a value in them. The workaround is to add an expression group matching all records with a value, and then negate it. Types_01

Parameters

A parameter is a dynamic value that can be incorporated into a query, allowing the query to adapt to different inputs and conditions. Parameters are defined at runtime based on user inputs or other external sources, making your queries more dynamic and flexible.

It is also used by facets, with each facet passing values to a specific parameter. For example a parameter called 'Color' with facet options 'Red', 'Blue', and 'Green'. When a user selects e.g. 'Red', this value is passed to the 'Color' parameter. The query then filters the products to include only those that match the selected color.

To use a parameter within an expression, you must do two things:

  • Create the parameter
  • Integrate it into an expression

To create a parameter:

  1. Navigate to the query where you want to add a parameter: Settings > Repositories > YourRepository > YourQuery
  2. In the Parameters section, click Manage
  3. In the Parameters section, click Add
  4. In the slide-over panel you need to:
    • Provide a name, e.g. 'Search', 'Category', or 'MinPrice'
    • Set the type name of the parameter which determines the kind of data it can hold, e.g. the type System.String is suitable for textual input like keywords or product names
    • If needed set a default value that is assigned to the parameter if no value is provided at runtime, this ensures that the query has a valid input to work with, even if the user does not provide one

Once created, a parameter will be listed in the parameters table:

Parameters_01.1

Integrating a Parameter into an Expression

After defining a parameter, the next step is to integrate it into an expression. This allows the query to utilize the dynamic value provided by the parameter to filter or manipulate data according to the user's input or other external sources.

Here’s how they are utilized:

  • Dynamic Filtering:
    • Parameters enable real-time filtering of data based on external inputs
    • Example: Using a 'Search' parameter to filter products by name based on user input
  • Flexibility and Adaptability:
    • They make queries more flexible and adaptable to varying conditions
    • Example: A 'Category' parameter can filter products by different categories selected by users
  • User-Driven Criteria:
    • Parameters allow queries to incorporate criteria that users define at runtime
    • Example: A 'PriceRange' parameter allows users to filter products within a specific price range

To integrate a parameter into an expression:

  1. Navigate to the Expressions section of your query and click Manage
  2. Go to the context menu of the group that you want to add an expression with a parameter to, and click New Expression
  3. Set up the expression and in the Type input, select Parameter
  4. In the Parameter section select your newly created parameter from the list: Parameters_02

Example: Parameter Definition and Integration

To get an idea how how this actually works in DynamicWeb, let's go through an example of defining a parameter and integrating it into an expression.

We'll create a parameter named 'ProductSearch' that allows users to filter products by name dynamically in e.g. a search box. We'll also use our dummy index from before as our source index:

ProductID Name Active Price
1 Laptop Active 1200
2 Headphones Not Active 150
3 Mouse Active 25
4 Keyboard Active 0
5 Monitor Not Active 300

Create the parameter:

  1. Navigate to the query where you want to add a parameter: Settings > Repositories > YourRepository > YourQuery
  2. In the Parameters section, click Manage
  3. In the Parameters tab, click Add
  4. Now we need to define the parameter:
    • Name: Name the parameter 'ProductSearch', since the parameter will be used within an expression that enables users to search for products
    • Type: Select the System.String[] type, since this enables the parameter to take in multiple input strings from the user
    • Default Value: Leave the default value empty, since the user will provide a value at runtime when they enter a search word NewParameters_01

To integrate the created parameter into an expression, follow these steps:

  1. Navigate to YourQuery
  2. Go to the Expression section and click Manage
  3. Go to the context menu of the group that you want to add the expression with a parameter to, and click New Expression
  4. Now we need to define the Expression:
    • Field: The field depends on the source index our repository is referring to. In our source index the fields available would be: 'ProductID', 'Name', 'Active', and 'Price'. Since we're creating a ProductSearch query, we would choose the 'Name' field
    • Operator: We would choose the operator 'Contains' for this example, since it looks for partial matches between the field value and the test value, matching the values from their beginning.
      • Other relevant operators could be: Equal as it checks if the field value is exactly equal to the test value or ContainsExtended which looks for a partial match between the field value and the test values, matching values anywhere in the string
    • Type: We would obviously choose 'Parameter' as the type and select the 'ProductSearch' parameter.

This simple parameter inside an expression would enable a user to search for products by name dynamically. For example, if a user enters "Laptop" into the search box, the query will filter the products to show only those with names starting with "Laptop".

Sorting

The data returned by a query can be organized in various ways using sorting. Typically, sorting is controlled at the app level - either through the Product Catalog app instance or the Query publisher app instance. However, you also have the option to set default sorting criteria directly on the query level.

To set the default sorting criteria on the query:

  1. Navigate to the query where you want to add a sorting: Settings > Repositories > YourRepository > YourQuery
  2. In the Sortings section, click Manage
  3. Under SortOrder, click Add
  4. Select a Field and a Sort direction
  5. Click OK and then Save and close

This is a default sorting and that any sorting applied at the app-level will override it.

Tip

Please note, that if a field is analysed, it cannot be sorted in a meaningful manner and will yield nonsense results. Instead, add a separate un-analysed product name field to the index and use that to sort a query result.

Data Types

Data types define the kind of data a variable can hold, such as integers, strings, dates, or booleans. They determine how data is compared, filtered, and processed.

Using the correct data type ensures efficient queries and accurate results. For example, using a decimal for prices ensures precise calculations, while a string for product names enables effective searching.

Overview of Data Types

Type Explanation Example
System.String Used to store a single string 'mountainbike'
System.String[] Used to store multiple strings 'mountainbike', 'electric'
System.Boolean Used to store a true or false value true
System.Boolean[] Used to store multiple true or false values true, false
System.DateTime Used to store a single date and time '2024-05-15'
System.DateTime[] Used to store multiple dates and times '2024-05-15', '2023-12-25'
System.Decimal Used to store a precise decimal number 99.99
System.Decimal[] Used to store multiple precise decimal numbers 99.99, 199.99
System.Double Used to store a double-precision floating-point number 99.99
System.Double[] Used to store multiple double-precision floating-point numbers 99.99, 199.99
System.Int16 Used to store a 16-bit integer 32,000
System.Int16[] Used to store multiple 16-bit integers 32,000, -32,000
System.Int32 Used to store a 32-bit integer 2,147,483,647
System.Int32[] Used to store multiple 32-bit integers 2,147,483,647, -2,147,483,648
System.Int64 Used to store a 64-bit integer 9,223,372,036,854,775,807
System.Int64[] Used to store multiple 64-bit integers 9,223,372,036,854,775,807, -9,223,372,036,854,775,808
System.Single Used to store a single-precision floating-point number 99.99
System.Single[] Used to store multiple single-precision floating-point numbers 99.99, 199.99
To top