# Import/Export CSV

Nected gives you an option to import or export Decision Tables in FEEL-compatible CSV format. This feature allows you to manage Decision Table logic using spreadsheet tools like Excel or Google Sheets.

### What is FEEL?

**Friendly Enough Expression Language (FEEL)** is a standardized expression language designed to bridge the gap between business logic and technical implementation. FEEL enables business analysts, domain experts, and developers to collaborate effectively by providing a syntax that is both human-readable and machine-executable. Originally defined as part of the [Decision Model and Notation (DMN) specification](https://www.omg.org/dmn/) by the Object Management Group (OMG), FEEL has become the standard for expressing business rules and decision logic.

In Nected, FEEL serves as the foundation for creating sophisticated decision logic within Decision Tables, Rules, and Workflows. By supporting FEEL-compatible expressions, Nected ensures that your business rules remain portable, standardized, and accessible to both technical and non-technical team members. Whether you're defining simple conditions or complex multi-criteria decisions, FEEL's intuitive syntax makes it easy to express your business logic clearly and precisely.

{% hint style="success" %}
DMN (Decision Model and Notation) support is also on our roadmap. Soon, you'll be able to import and manage complete DMN models directly within Nected, making it easier to align with industry-standard decision modeling practices.
{% endhint %}

Before importing or exporting the CSV file, here are the prerequisites that you need to understand and configure accordingly:

### What should the FEEL-compatible CSV File Format be?

Whenever you're preparing a CSV file for rule testing or bulk evaluations, the structure must strictly follow a **FEEL-compatible format**. Each column should represent a valid FEEL expression bound to a data type (e.g., numeric, string, date, datetime). Each row represents a different test case or input set.

| **status** | **numeric({{.customInput.Num1}})** | **numeric({{.customInput.Num1}})** | **date({{.customInput.Date1}})**                          | **dateTime({{.customInput.DateTime1}})** |   | **string(result)** | **dateTime(keyName)**                 |
| ---------- | ---------------------------------- | ---------------------------------- | --------------------------------------------------------- | ---------------------------------------- | - | ------------------ | ------------------------------------- |
| TRUE       | 1                                  | 2                                  | date("2025-11-10")                                        | datetime("2025-06-27T16:27:00+05:30")    |   | "Atul1"            | datetime("2025-06-27T17:28:43+05:30") |
| TRUE       | fx(var a=10;a)                     | < fx(var a=10;a)                   | fx(var a = "2025-11-10";a)                                | > datetime("2025-06-27T17:06:02+05:30")  |   | "Atul1"            | datetime("2025-06-27T17:28:43+05:30") |
| TRUE       | < 10                               | not(\[12...231])                   | != fx(var a = "2025-11-10";a)                             | < datetime("2025-06-27T17:06:09+05:30")  |   | "Atul1"            | datetime("2025-06-27T17:28:43+05:30") |
| TRUE       | >= 1                               | >= 1                               | \[fx(var a = "2025-11-10";a)...date("{{.globalVar.fs}}")] | != datetime("2025-06-27T17:06:24+05:30") |   | "Atul1"            | datetime("2025-06-27T17:28:43+05:30") |

Download the sample CSV file to get an idea how to write the CSV file:

{% file src="<https://4290782554-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLg716fCfV8IUwXQygkTG%2Fuploads%2FzKiWAB6RyTCJfkizq5sN%2FFEEL_CSV.csv?alt=media&token=922d3f5a-0741-4fab-92f4-2e8e61a9a77b>" %}

### 2. FEEL Compatible Operators for CSV

When creating FEEL expressions in your CSV files, use these operators that are compatible with Nected's platform. This table shows the FEEL syntax, corresponding Nected operators, their purpose, and usage examples.

| FEEL Operator       | Nected Operator         | Purpose                                                 | Examples (Static / Token / Function)                                                                   |
| ------------------- | ----------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Existence**       |                         |                                                         |                                                                                                        |
| `exists()`          | **EXISTS**              | Confirms that the current field is present and not null | `exists()`                                                                                             |
| `not(exists())`     | **NOT EXISTS**          | Confirms that the current field is missing or undefined | `not(exists())`                                                                                        |
| `null`              | **NULL**                | Checks for an explicit `null` value                     | `null`                                                                                                 |
| `not(null)`         | **NOT NULL**            | Checks that the value is anything except `null`         | `not(null)`                                                                                            |
| **Comparison**      |                         |                                                         |                                                                                                        |
| `==`                | **EQUAL**               | Tests equality                                          | `== 10` / `==ABC` or, simply writing the value `10` / `== {{.customInput.Name}}` / `== fx(var a=10;a)` |
| `!=`                | **NOT EQUAL**           | Tests inequality                                        | `!= "Blocked"` / `!= {{.globalVar.status}}` / `!= fx(var s="X";s)`                                     |
| `>`                 | **GREATER THAN**        | Greater‑than comparison                                 | `> 21` / `> {{.customInput.age}}`                                                                      |
| `<`                 | **LESS THAN**           | Less‑than comparison                                    | `< 1000` / `< {{.globalVar.maxAmount}}`                                                                |
| `>=`                | **GREATER THAN EQUALS** | Greater‑than‑or‑equal comparison                        | `>= 75` / `>= {{.globalVar.minScore}}`                                                                 |
| `<=`                | **LESS THAN EQUALS**    | Less‑than‑or‑equal comparison                           | `<= 5000` / `<= {{.customInput.limit}}`                                                                |
| **Range**           |                         |                                                         |                                                                                                        |
| `[x...y]`           | **BETWEEN**             | Inclusive range check                                   | `in [1...3]` / `in [1...{{.globalVar.base_price}}]`                                                    |
| `not([x...y])`      | **NOT BETWEEN**         | Outside inclusive range                                 | `not(in [0...50])` / `not(in [0...{{.globalVar.minPass}}])`                                            |
| `(x..y)`            | **BETWEEN EXCLUSIVE**   | Exclusive range check                                   | `in (100..1000)` / `in ({{.globalVar.minAmount}}..{{.globalVar.maxAmount}})`                           |
| **String**          |                         |                                                         |                                                                                                        |
| `contains()`        | **CONTAINS**            | Checks for substring                                    | `contains("John")` / `contains("{{.globalVar.searchTerm}}")`                                           |
| `not(contains())`   | **NOT CONTAINS**        | Confirms substring absence                              | `not(contains("spam"))` / `not(contains("{{.globalVar.blocked}}"))`                                    |
| `startsWith()`      | **START WITH**          | Checks prefix                                           | `startsWith("ABC")` / `startsWith("{{.globalVar.prefix}}")`                                            |
| `not(startsWith())` | **NOT START WITH**      | Confirms prefix absence                                 | `not(startsWith("TEMP"))` / `not(startsWith("{{.globalVar.tempPrefix}}"))`                             |
| `endsWith()`        | **END WITH**            | Checks suffix                                           | `endsWith(".com")` / `endsWith("{{.globalVar.allowedDomain}}")`                                        |
| `not(endsWith())`   | **NOT END WITH**        | Confirms suffix absence                                 | `not(endsWith(".tmp"))` / `not(endsWith("{{.globalVar.tempExt}}"))`                                    |
| **List**            |                         |                                                         |                                                                                                        |
| `in`                | **IN**                  | Membership test                                         | `in ["Active","Pending"]` / `in {{.globalVar.statusList}}`                                             |
| `not(in)`           | **NOT IN**              | Non‑membership test                                     | `not(in ["Blocked","Banned"])` / `not(in {{.customInput.List1}})`                                      |
| `empty()`           | **EMPTY**               | Checks for empty list                                   | `empty()`                                                                                              |
| `not(empty())`      | **NOT EMPTY**           | Checks for non‑empty list                               | `not(empty())`                                                                                         |
| `containsIn()`      | **CONTAINS IN**         | Validates that every item exists in a reference list    | `containsIn ["Admin","User"]` / `containsIn {{.customInput.roles}}`                                    |
| `not(containsIn())` | **NOT CONTAINS IN**     | Detects missing items with respect to reference list    | `not(containsIn ["Special"])`                                                                          |
| `matchAll()`        | **MATCH ALL**           | Confirms that all specified items are present           | `matchAll ["GPS","WiFi"]` / `matchAll {{.customInput.features}}`                                       |
| `not(matchAll())`   | **NOT MATCH ALL**       | Confirms that at least one item is missing              | `not(matchAll ["ID","Proof"])`                                                                         |
| **Boolean**         |                         |                                                         |                                                                                                        |
| `true`              | **TRUE**                | Boolean literal `true`                                  | `true`                                                                                                 |
| `false`             | **FALSE**               | Boolean literal `false`                                 | `false`                                                                                                |
| `even()`            | **EVEN**                | Checks if current number is even                        | `even()`                                                                                               |
| `not(even())`       | **ODD**                 | Checks if current number is odd                         | `not(even())`                                                                                          |
| **Date/Time**       |                         |                                                         |                                                                                                        |
| `date()`            | **DATE**                | Creates a date value                                    | `date("2025-01-15")` / `date("{{.customInput.dateString}}")`                                           |
| `datetime()`        | **DATETIME**            | Creates a datetime value                                | `datetime("2025-01-15T10:30:00")` / `datetime("{{.customInput.dateTimeString}}")`                      |
| **Advanced**        |                         |                                                         |                                                                                                        |
| `fx()`              | **ExcelFormula**        | Evaluates an Excel‑style formula                        | `fx(var a=10;a*2)` / `fx(var a={{.customInput.value}};a*{{.globalVar.mult}})`                          |
| `js()`              | **JsFormula**           | Evaluates a JavaScript expression                       | `js: Math.round(10.4)` / `js: Math.round({{.customInput.value}}*{{.globalVar.rate}})`                  |

**Refer to the** [**Pre-Configured Operators documentation**](https://docs.nected.ai/nected-docs/references/pre-configured-operators) for the complete list of available operators and their syntax. This ensures that your CSV expressions will work correctly when imported into Nected Decision Tables. **Example expressions:**

1. `age >= 18` (numeric comparison)
2. `status = "Active"` (string equality)
3. `category in ["Premium", "Gold"]` (list membership)
4. `applicationDate between "2024-01-01" and "2024-12-31"` (date range)
5. `age >= 18` (numeric comparison)
6. `status = "Active"` (string equality)
7. `category in ["Premium", "Gold"]` (list membership)
8. `applicationDate between "2024-01-01" and "2024-12-31"` (date range)

**Available Token Types:**

* **customInput**: `{{.customInput.fieldName}}` - User-defined inputs
* **globalVar**: `{{.globalVar.variableName}}` - Global variables
* **dataSet**: `{{.dataSet.fieldName}}` - Dataset references
* **outputData**: `{{.outputData.fieldName}}` - Previous rule outputs
* **systemVar**: `{{.systemVar.NULL}}`, `{{.systemVar.ExecutionId}}`, `{{.systemVar.Environment}}`

### Importing Decision Tables from FEEL-compatible CSV

You can import Decision Table data from CSV files that follow the FEEL-compatible format. This allows you to manage your decision logic using external spreadsheet tools and bulk import rules into Nected.

{% hint style="info" %}
Only the Table data will be imported, not the dependencies i.e., input attributes are not included in CSV import. To import the complete decision table, import it using by default way.
{% endhint %}

Follow these steps to import a FEEL-compatible CSV to the decision table:

1. **Access Import Function**
   * Open the Decision Table editor where you want to import the CSV from the dashboard or create a new one.
   * Click the **Import** button in the bottom of the decision table. It will open a popup like below:

     ![image.png](https://4290782554-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLg716fCfV8IUwXQygkTG%2Fuploads%2Fw6qlOrJM5qMdygjw4G52%2FCSV%20Import%20Export%20for%20DMN%20Rule%20\(1\).png?alt=media\&token=b97a8e53-a03f-4026-a223-0d9804958535)
2. **Upload and Preview**
   * Click **Upload file** and select your prepared CSV file
   * After it successfully got imported, click on “**Continue with Import**” button.

     ![image.png](https://4290782554-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLg716fCfV8IUwXQygkTG%2Fuploads%2FqbKIZ6pKkYQTOz8zPRSb%2FCSV%20Import%20Export%20for%20DMN%20Rule%20\(2\).png?alt=media\&token=defb4221-2ed4-4659-8882-99dcff73b5d9)

If everything with your csv file is correct, then the rows will be simply imported and appended into the decision table; else you’ll see the errors in your csv file from this popup:

![image.png](https://4290782554-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLg716fCfV8IUwXQygkTG%2Fuploads%2FzelhIYyoid79WVk7knLJ%2FCSV%20Import%20Export%20for%20DMN%20Rule%20\(3\).png?alt=media\&token=941db33a-f65f-479e-8cbc-e66c1b84fe89)

### Exporting Decision Tables to FEEL-compatible CSV

Export your existing Decision Tables to CSV format for external editing, backup, or sharing with stakeholders who prefer working with spreadsheet applications.

Steps to Export the decision table as FEEL compatible format is very simple:

1. Open the Decision Table to ensure it contains the data you want to export.
2. Click the **Export** button in the Decision Table

{% hint style="info" %}
To Export the Decision Table to FEEL compatible csv format, their should be at least one property added in the DT.
{% endhint %}

### Not Supported Features

When using CSV import/export for Decision Tables, certain advanced features are not supported. If your Decision Table contains any of these elements, CSV export will not be possible:

**1. Group Conditions** If you've created grouped conditions in your Decision Table using the "Group" functionality, CSV export will not work. Group conditions that combine multiple criteria with complex logical relationships cannot be represented in the flat CSV structure.

**2. Relative Dates** Decision Tables that use relative date conditions (such as "last 30 days", "next week", or "3 months ago") are not supported in CSV export. These dynamic date references cannot be accurately converted to the static CSV format.

### Conclusion

The CSV import/export functionality for Decision Tables provides a powerful way to manage your business rules using familiar spreadsheet tools while maintaining full compatibility with Nected's FEEL expression language. This feature enables seamless collaboration between technical and business teams, allows for bulk rule management, and simplifies the process of maintaining complex decision logic.

By leveraging FEEL-compatible operators and Nected's comprehensive token system, you can create sophisticated decision rules in CSV format that seamlessly integrate with your existing workflows. Whether you're migrating existing rules, collaborating with stakeholders, or managing large-scale decision tables, the CSV format offers the flexibility and ease-of-use needed for effective decision management.

Remember to follow the format specifications and operator guidelines outlined in this documentation to ensure successful import and export operations. For any advanced features not supported in CSV format, continue using the native Nected Decision Table interface to maintain full functionality.
