---
title: "Build a query using LINQ"
canonical: "https://docs.devo.com/space/latest/95191261/Build%20a%20query%20using%20LINQ"
format: markdown
---
> Macro (toc)

## Overview

Instead of using the Devo interface, queries can also be directly written using LINQ language.

LINQ is the query language used by Devo to query data tables. <span style="color: #000000">LINQ syntax is very flexible as it allows to make a query expression very close to the data discovery process by:</span>

1. <span style="color: #000000">selecting the source data table (using </span>`from`<span style="color: #000000">)</span>
2. <span style="color: #000000">filtering data (using </span>`where`<span style="color: #000000">)</span>
3. <span style="color: #000000">creating new fields (using </span>`select` and optionally `as`<span style="color: #000000">...)</span>
4. <span style="color: #000000">grouping the data by a time value (using </span>`group every`<span style="color: #000000"> and</span> `every`<span style="color: #000000">)</span>
5. <span style="color: #000000">applying aggregation operations over the grouped data (using </span>`select`<span style="color: #000000">... </span>`as`<span style="color: #000000">...)</span>

```
from <table name>
group every <server period> by <field1>, <field2>
every <browser period>
select <aggregation operation 1>(<field>) as <NewfieldName1>,
<aggregation operation 2>(<field>) as <NewfieldName2>,
```

<span style="color: #000000">For example, the following is a LINQ query where we want to retrieve only those events with status code 404 grouped </span><span style="color: #282828">every 10 minutes, displaying the</span><span style="color: #282828">** method **</span><span style="color: #282828">and </span><span style="color: #282828">**clientIpAddress **</span><span style="color: #282828">fields.</span><span style="color: #000000"> Additionally, we have created the </span>**myCount**<span style="color: #000000"> field to count the records in each interval. For more examples using different operations, see the </span>[LINQ query examples](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95191293)<span style="color: #000000"> section.</span>

```
from demo.ecommerce.data
where statusCode = 404
group every 10m by method, clientIpAddress
every 10m
select count() as myCount
```

![image](media://06024707-adbe-46c6-8ede-0107a9e291f0)

There are two different ways of accessing the query editor, where you can write your LINQ query:

![image](media://3cec8cba-dc3c-488b-89c5-c08de2a042e1)

## LINQ clauses

Find below a description of each of the general LINQ clauses you can use to query your data.

<details>
<summary>Filter data using LINQ</summary>

These are the necessary clauses you need to add to your LINQ query in order to perform a filtering operation:

```
from <table name> 
where <filter1>,
<filter2>
...
```

For example, the following query performs a filter to get only those events where the number of bytes sent is greater than 800:

```
from demo.ecommerce.data 
where bytesTransferred > 800
```

And this one returns the events where the client IP address is not null and the bytes transferred are less than 1000:

```
from demo.ecommerce.data 
where isnotnull(clientIpAddress),
   bytesTransferred < 1000
```

Learn how to filter using the search window interface in the following article: [Filter data](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95191041).
</details>

<details>
<summary>Group data using LINQ</summary>

These are the necessary clauses you need to add to your LINQ query in order to group data:

| <u>Time-based</u> | <u>Non-time-based</u> |
| --- | --- |
| ```
group every <server period> by <field1>, <field2>
every <client period>
``` | ```
group every - by <field1>, <field2>
```<br>```
group by <field1>, <field2>
``` |

Adding two different grouping periods might look like an unnecessary complexity, but it brings many advantages, such as the optimization of the query response. The server period is smaller than the client period, so the information is sent from the server in smaller chunks. This allows you to apply other grouping periods from the browser without having to query the server again. An `every 0` is also allowed in the case you don’t want any grouping period.

For example, the following query groups data by IP address and status code every 3 hours (client period). The server period has been set to 30 minutes to optimize performance.

```
from demo.ecommerce.data 
group every 30m by clientIpAddress, statusCode
every 3h
```

Learn how to group using the search window interface, as well as the details about client and server periods in the following article: [Group data](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95191181).
</details>

<details>
<summary>Aggregate data using LINQ</summary>

These are the necessary clauses you need to add to your LINQ query in order to perform an aggregation operation. You must always group the data before aggregating data. 

```
from  <table name>
group every <server period> by <field1>, <field2>
every <client period>
select  <aggregation operation 1>(<field>) as <NewfieldName1>,
<aggregation operation 2>(<field>) as <NewfieldName2>,
...
```

For example, this query returns the average of bytes transferred every 5 minutes for each status code.

```
from demo.ecommerce.data 
group every 5m by statusCode 
every 5m select 
avg(bytesTransferred) as AvgOfBytes
```

And this one returns the first non-null client IP address every 3 hours for each method.

```
from demo.ecommerce.data 
group every 30m by method 
every 3h 
select nnfirst(clientIpAddress) as FirstNonNullIP
```

Learn how to aggregate using the search window interface: [Aggregate data](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95191226).
</details>

<details>
<summary>Create new fields using LINQ</summary>

These are the necessary clauses you need to add to your LINQ query in order to perform a create field operation. You must always include the `select` operator followed by the operation name and field. 

Optionally, you can add an `as` operator if you want to choose the name of the new field. In case you don't add an `as` operator, the name of the new field will be the *operation(field).*

```
from <table name>
 select  <aggregation operation 1>(<field>) as <NewfieldName1>,
  <aggregation operation 2>(<field>) as <NewfieldName2>,
...
```

For example, the following query creates two fields showing the corresponding latitude and longitude values of the IPs in the **ClientIpAddress** field of the table.

```
from demo.ecommerce.data
 select mmlatitude(clientIpAddress),
  mmlongitude(clientIpAddress)
```

And this one displays the definitions of the status codes in a new field.

```
from demo.ecommerce.data 
select decode(statusCode, 200, "Successful Login", 400, "Bad/Invalid Request", 401, "Invalid Password/Username") as StatusCodeMessages
```

Learn how to create fields using the search window interface: [Create fields](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95191142).
</details>