Skip to content

[DUX-478] Add View Entity Document Changes to Existing Documentation #9401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: Mendix-11
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This feature is currently in beta. For more information, see [Beta and Experimen

## Introduction

A view entity represents the result set of a stored [OQL query](/refguide/oql/) and can be used similarly to a [persistable entity](/refguide/persistability/#persistable). This concept is similar to the function of views in general database technology. Whenever a view entity is retrieved via a page or a microflow, the corresponding OQL query runs and fetches the relevant data. Consequently, the result set of a view entity is not stored as a separate table in the database (like a materialized view). Instead, the query runs each time the view entity is accessed, dynamically retrieving the data.
A view entity represents a dynamic set of data retrieved using a stored [OQL query](/refguide/oql/) and can be used similarly to a [persistable entity](/refguide/persistability/#persistable). This concept is analogous to views commonly found in relational database systems. Whenever a view entity is accessed through a page or microflow, the associated OQL query executes to retrieve the relevant data dynamically. Unlike materialized views, the results of a view entity are not stored as a separate table in the database. Instead, the query is executed each time the view entity is accessed, ensuring the data retrieved is always up-to-date.

During modeling, changes to the underlying entities used in the OQL query affect the options available within the query. At runtime, any changes to the data in the underlying entities immediately impact the data available through the view entity.

Expand All @@ -31,39 +31,39 @@ Your app must use OQL version 2 to use view entities. You can change this settin

Double-click a view entity to open its Properties dialog box. An example of a view entity's properties dialog box is represented in the image below:

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/customer-with-address.png" width="500" >}}
{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/view-entity.png" width="500" >}}

An example of a view entity's properties dialog is represented in the image below:

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/view-entity-dialog.png" width="500" >}}

To open the oql query, click the **Show** button in the view entity dialog:

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/view-entity-document.png" width="500" >}}

Alternatively, you can right-click the entity and click **Go to oql query** from the context menu:

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/view-entity-contextual-menu.png" width="500" >}}

View entity properties consist of the following sections:

* [General](#general)
* [OQL editor](#oql-editor)
* [Access rules](#access-rules)
* [Documentation](#documentation)
* [OQL Query Tab Editor](#view-entity-doc-tab-editor)

### General Section {#general}

#### Name {#name}

The name property defines the name of the view entity. This name is used to refer to the view entity in forms, microflows, queries, constraints, etc.
The name property defines the name of the view entity and oql query document. This name is used to refer to the view entity in forms, microflows, queries, constraints, etc.

The name has to be unique only within the domain model of a module. You can have two view entities with the same name, provided they are in the domain models of different modules.

#### Image {#image}

The image property can be used to associate an image with a view entity. In the domain model, this image is shown in the top-left corner of the view entity. The image is also shown in other places where view entities are mentioned, such as the entity selection pop-up window when selecting an entity for a data view.

### OQL Editor Section {#oql-editor}

This section contains the **OQL editor** and the **Preview data** table.

The **OQL editor** allows you to write the query that defines this view entity. While writing this query, the editor suggests names of the entities and attributes in your domain model, as well as allowed clauses, operators, and functions. If the query is not valid, a list of validation errors will be displayed underneath the editor with the line and column number of the place where the error was found.

The resulting names and types of the attributes will be displayed as column headers in the **Preview data** table. You can view the resulting data set of your OQL query by clicking **Run Query**, which enables Studio Pro to retrieve the data from the database that is configured in your app settings. The database type of the active configuration is also listed in the header of the section. To use this functionality, your app must be running.

{{% alert color="warning" %}}
The **Preview data** table tries to retrieve the data using your OQL query from the running app. This means if you have changed your domain model since you last started the app, you can run into errors when the OQL query uses attributes or entities that do not yet exist in the version of the app that is running.
{{% /alert %}}

### Access Rules {#access-rules}

When the security level of the app is set to **Production**, the **Access rules** tab becomes available in the view entity properties.
Expand All @@ -76,6 +76,21 @@ Direct writing from the view entity to its source entities is not supported, but

You can add any local information about the view entity in this tab. This is also available to other users working on the app.

### OQL Query Tab Editor {#view-entity-doc-tab-editor}

This section contains the **OQL editor** and the **Preview data** table.

The **OQL editor** runs in the oql query tab, where interaction with various UI components in Studio Pro is possible, such as the Properties pane and a real-time view to preview your data.

The **OQL editor** allows you to write the query that defines this view entity. While writing the query, the editor suggests names of the entities and attributes in your domain model, as well as allowed clauses, operators, and functions. If the query is not valid, a list of validation errors are displayed underneath the editor with the line and column number of the place where the error was found.

The resulting names and types of the attributes are displayed as column headers in the **Preview data** table. You can view the resulting data set of your OQL query by clicking **Run Query**, which enables Studio Pro to retrieve the data from the database that is configured in your app settings. The database type of the active configuration is also listed in the header of the section. To use this functionality, your app must be running.

{{% alert color="warning" %}}
The **Preview data** table tries to retrieve the data using your OQL query from the running app. This means if you have changed your domain model since you last started the app, you can run into errors when the OQL query uses attributes or entities that do not yet exist in the version of the app that is running.
{{% /alert %}}


## Using a View Entity

After creating a view entity in the domain model, it can be used in microflows and pages like any other entity. For more information, see [Use View Entities](/refguide/use-view-entities/) and [OQL]( /refguide/oql/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You have a module that manages the inventory and stock of your shop products. Yo

With the add-on enabled, you should see an additional configurable property in the documents and other elements of your module called **Export level**. This is set to **Hidden** by default, which means users of your add-on cannot access them.

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/abstracting-data/export-level.png" width="500" >}}
{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/abstracting-data/export-level-hidden.png" width="500" >}}

## Create a View Entity

Expand All @@ -49,6 +49,5 @@ You want to make an interface that shows products where you can filter the resul

3. Double-click **ProductCategoryVE** and set the export level to **Usable**.

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/abstracting-data/usable.png" width="500" >}}

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/abstracting-data/export-level-usable.png" width="500" >}}
4. Export the add-on module by right-clicking it and selecting **Export add-on module package**.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ weight: 10

## Introduction

View entities allow you to retrieve, transform, and aggregate your data. They represent a set of stored OQL queries that can be used similarly to [persistable entities]( /refguide/persistability/#persistable). The data that view entities contain is determined when you retrieve the data.
View entities enable the retrieval, transformation, and aggregation of data within Mendix applications. Each view entity is defined by a corresponding **Object Query Language (OQL) query** specifying the data retrieval logic. This configuration allows view entities to function similarly to [persistable entities]( /refguide/persistability/#persistable). The data that view entities contain is determined when you retrieve the data.

You can perform operations such as sorting, paging, and filtering using view entities. The entire query is executed by the database, often resulting in faster performance compared to executing multiple independent retrieves. A view entity fetches the data you need from the database and allows data transformation and aggregation. With view entities, you can:

Expand Down Expand Up @@ -36,13 +36,35 @@ Retrieving data from your database can result in very large and complex queries.

View entities offer an additional powerful way to improve reusability, readability, and maintainability. You can use them to combine simple queries into more complex ones. A query defines a set of data, which can then be further refined to retrieve more detailed information. A view entity can be also composed of data defined by other view entities.

For example, the view entity pictured below lists all customers at an organization that are over age 18. The entity includes their full name, age, and delivery and billing addresses.

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/customer-with-address.png" width="500" >}}
For example, the view entity pictured below lists all customers at an organization that are over age 18. The view entity includes their full name, age, and delivery and billing addresses.

```sql
FROM Shop.Customer AS c
LEFT JOIN c/Shop.BillingAddress/Shop.Address as ba
LEFT JOIN c/Shop.DeliveryAddress/Shop.Address as da
WHERE datediff(YEAR,c.DateOfBirth,'[%CurrentDateTime%]') > 18
SELECT
c.CustomerId as CustomerId
,c.LastName + ', ' + FirstName as FullName
,datediff(YEAR, c.DateOfBirth,'[%CurrentDateTime%]') as Age
,ba.Streetname + ' ' + ba.StreetNumber + ' ' + ba.Zipcode + ' ' + ba.City + ' ' + ba.Country as BillingAddress
,da.Streetname + ' ' + da.StreetNumber + ' ' + da.Zipcode + ' ' + da.City + ' ' + da.Country as DeliveryAddress
```

Age is determined for each customer by calculating the difference in years between the current day and the customer’s date of birth. Another view entity can then count the number of customers that were born in each decade and group them appropriately.

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/customer-per-decade.png" width="500" >}}
```sql
FROM
(
FROM HowToThink.CustomerWithAddressVE as c SELECT CAST(c.Age:10 as integer) * 10 as AgeBucket ,
c.CustomerId as CustomerId) as b
GROUP BY b.AgeBucket
SELECT b.AgeBucket as AgeBucketStart ,
b.AgeBucket + 9 as AgeBucketEnd ,
COUNT(b.CustomerId) as CustomerCount
ORDER BY b.AgeBucket
LIMIT 10
```

The original customer view included address information, but most database optimizers will see that this information is not relevant when counting customers by age, so this information is excluded when retrieving the data. However, the information is still present and can be generated, if requested.

Expand All @@ -54,7 +76,18 @@ Filtering attributes is one way to configure your queries. For example, assume y

Alternatively, you can store the parameter value in the database, then use that value in your view entity. For example, the image below is of a view entity that returns the data of the *Product* entity in the language of the current user.

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/product-language.png" width="500" >}}
```sql
FROM Shop.Product as p
LEFT JOIN System.User as u ON (u.ID = '[%CurrentUser%]')
LEFT JOIN u/System.User_Language/System.Language as l
LEFT JOIN p/Shop.ProductTranslations_Product/Shop.ProductTranslations as t ON (t.LanguageCode = l.Code)
SELECT p.ID as ID,
p.ProductId as ProductId,
COALESCE(t.Name, p.Name) as Name,
COALESCE(t.Description, p.Description) as Description,
p.WeightInGrams as WeightInGrams,
l.Code as UserLanguageCode
```

This is done by joining an entity that has all the necessary translations and filtering it by the language of the current user. Coalesce is used to return the default language in case there is no translation is available.

Expand All @@ -70,11 +103,27 @@ Persistable entity access rules are not applied when using view entities. Instea

In the following example, a view entity is used to implement multitenant security. The view entity *CustomersVE* only returns the customers that belong to the tenant of the current user. Any additional view entity that uses *CustomersVE* instead of the persistable entity *Customer* will only get data belonging to the tenant of the user.

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/active-tenant.png" width="500" >}}
```sql
FROM Shop.Customer as c
JOIN ShopViewSamples.CurrentUserVe u ON (u.UserTenantId = c.TenantId)
SELECT c.CustomerId as CustomerId,
c.FirstName as FirstName,
c.LastName as LastName,
c.EmailAddess as EmailAddess,
c.DateOfBirth as DateOfBirth
```

Instead of joining with the `[%CurrentUser%]` expression, this example joins with a view entity that only returns one object: the current user and related details, such active language and tenant ID. This simplifies use of user information for other view entities.

{{< figure src="/attachments/refguide/modeling/domain-model/use-view-entities/current-user.png" width="500" >}}
```sql
FROM System.User as u
LEFT JOIN u/System.User_Language/System.Language as l
LEFT JOIN u/Shop.UserTenant_User/Shop.UserTenant as t
WHERE (u.ID = '[%CurrentUser%]')
SELECT u.Name as UserName ,
l.Code as UserLanguageCode ,
t.TenantId as UserTenantId
```

## Performance

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ An advantage of separating *OrderUpdate* from *OrderLine* is that it is easier t
To view the latest status of an order, follow the steps below:

1. Open your domain model and add a view entity named *LatestOrderStatusVE*.
2. Add the following query to the OQL editor:
2. Click **Show** to open the oql query.
3. Add the following query to the oql query to OQL editor:

```sql
SELECT
Expand Down Expand Up @@ -57,7 +58,20 @@ For more information on different OQL clauses, see [OQL Version 2 Features](/ref

The final result is a list with only the latest update of each order:

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/view-entity-data-versioning/entity-properties.png" width="500" >}}
```sql
SELECT o.OrderId AS OrderId,
o.RequiredDate AS RequiredDate,
u.OrderStatus AS OrderStatus,
u.UpdateDate AS UpdateDate
FROM Shop.OrderInfo o
JOIN O / Shop.OrderUpdate_Order Info / Shop.OrderUpdate u
JOIN
( SELECT u.OrderId AS OrderId,
MAX (u.UpdateDate) AS UpdateDate
FROM Shop.OrderUpdate u
GROUP BY u.OrderId) latest ON (latest.OrderIdo.OrderId
AND latest.UpdateDate u.UpdateDate)
```

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/view-entity-data-versioning/data-grid.png" width="500" >}}

Expand All @@ -71,6 +85,21 @@ WHERE u.UpdateDate < CAST('1997/08/17' as DATETIME)

This addition retrieves the order status for one specific date:

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/view-entity-data-versioning/entity-properties-2.png" width="500" >}}
```sql
SELECT o.OrderId AS OrderId,
o.RequiredDate AS RequiredDate,
u.OrderStatus AS OrderStatus,
u.UpdateDate AS UpdateDate
FROM Shop.ORDER
Info o
JOIN O / Shop.OrderUpdate_Order Info / Shop.OrderUpdate u
JOIN
( SELECT u.OrderId AS OrderId,
MAX (u.UpdateDate) AS UpdateDate
FROM Shop.OrderUpdate u
GROUP BY u.OrderId) latest ON (latest.OrderId = o.OrderId
AND latest.UpdateDate u.UpdateDate)
WHERE u.UpdateDate < CAST ( '1997/08/17' AS DATETIME)
```

{{< figure src="/attachments/refguide/modeling/domain-model/view-entities/view-entity-data-versioning/data-grid-2.png" width="500" >}}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ You want to export a report of customer information in JSON format. The report s

Create a view entity to join the customer and address tables. To do this, follow the steps below:

1. Create a view entity and name it *CustomerVE*.
2. Add the following query to the OQL editor:
1. Create a view entity and name it *CustomerVE*.
2. Open the CustomerVE entity and click **Show** to access the query editor.
3. Add the following query to the OQL editor:

```sql
SELECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,4 @@ The table below presents all the third-party services each Maia capability uses
| Maia Rewrite | [Mistral 7B](https://mistral.ai/news/announcing-mistral-7b/) hosted in Mendix AWS environment | The draft question description from users |
| Maia Summarize | [Mistral 7B](https://mistral.ai/news/announcing-mistral-7b/) hosted in Mendix AWS environment | [Community](https://community.mendix.com/p/community) threads |
[Maia Create User Story | [Mistral 7B](https://mistral.ai/news/announcing-mistral-7b/) hosted in Mendix AWS environment | User prompts ]
| Maia for OQL | [Claude in Amazon Bedrock](https://aws.amazon.com/bedrock/claude/) | Project context to fulfill user prompt request |
Loading