> For the complete documentation index, see [llms.txt](https://olivers-expression-lab.gitbook.io/filter-expressions-in-fme/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://olivers-expression-lab.gitbook.io/filter-expressions-in-fme/logical-operators.md).

# Logical Operators

In previous chapters we learned how to do different attributive and spatial queries.&#x20;

Let's combine them by using Logical Operators.

## OR

Let's start with the **OR-Operator** (logical disjunction).

We will use the parking decks-WFS provided by Hanseatic City of Hamburg we already used in [Comparison Operators](/filter-expressions-in-fme/comparison-operators.md).

| Parameter      | Value                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------ |
| WFS URL        | <https://qs-geodienste.hamburg.de/HH_WFS_Verkehr_opendata?SERVICE=WFS>                                       |
| Version        | 2.0.0                                                                                                        |
| Features Types | verkehr\_parkhaeuser                                                                                         |
| Max Features   | leave blank                                                                                                  |
| xmlns          | de.hh.up="<https://registry.gdi-de.org/id/de.hh.up>"                                                         |
|                | <p>preise (de) = fees (en)<br>kostenlos (de) = free of charge (en)<br>keine Gebühr (de) = no charge (en)</p> |

The services provides an attribute called "preise", i.e. fees.

First, we will look for all parking decks, which can be used free of charge (**kostenlos**), at least for some time (half an hour or an hour).

The word "kostenlos" occurs in different mixtures like

* 1\. Stunde **kostenlos**|2. Stunde 1,20 EUR | jede weitere Std. 1,50 EUR|Tageshöchstsatz k. A.
* 1\. Stunde **kostenlos**|jede weitere Std. 1,50 EUR|Tageshöchstsatz 15,00 EUR
* halbe Stunde: **kostenlos**|2. halbe Stunde: 0,50 EUR|2. Stunde: 1,00 EUR| (...)

Remember what we learned in [Comparison Operators](/filter-expressions-in-fme/comparison-operators.md) about **Wildcards** using the **PropertyIsLike**-Operator.

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
		<fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>*kostenlos*</fes:Literal>
		</fes:PropertyIsLike>
</fes:Filter>
```

Using this filter expression, the service will return **5** features (at the time of publication of this chapter):

* 10047 Elbe Einkaufszentrum (EEZ)
* 10076 Alstertal Einkaufszentrum (AEZ) Ost
* 10094 Harburg Carree
* 10116 Alstertal Einkaufszentrum (AEZ) Mitte
* 10117 Alstertal Einkaufszentrum (AEZ) West

Next, we will look for all parking decks with no charges (**keine Gebühren**) using the well-known **PropertyIsEqualTo**-Operator.

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
		<fes:PropertyIsEqualTo>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>keine Gebühren</fes:Literal>
		</fes:PropertyIsEqualTo>
</fes:Filter>
```

The WFS will return **3** additional features:

* 10089 Sander Markt
* 10090 Frascatiplatz
* 10091 Lohbrügger Marktplatz

Instead of sending two separate (disjoined) requests, we can combine them into one single request using the OR-Operator as shown below:

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
	<fes:Or>
		<fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>*kostenlos*</fes:Literal>
		</fes:PropertyIsLike>
		<fes:PropertyIsEqualTo>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>keine Gebühren</fes:Literal>
		</fes:PropertyIsEqualTo>
	</fes:Or>
</fes:Filter>
```

The only simple trick is to **embrace your expressions** (to be precise, the conditions within the expression) **by the logical operator** needed, i.e.

```
OR
    CONDITION 1
    CONDITION 2
    ...
/OR
```

```
AND
    CONDITION 1
    CONDITION 2
    ...
/AND
```

If you're a programmer, this may be unfamiliar for you because you normally connect conditions by logical operators like this:

```
CONDITION 1 OR CONDITION 2 OR CONDITION 3
```

So please keep in mind: logical operators embrace conditions within filter expressions.

## AND

Recapitulating what we have learned, using other logical operators is really easy:

* take two or more filter expressions&#x20;
* make sure, that they are working stand-alone (please test them!)&#x20;
* combine them by enclosing them by logical operators

To do so, we will have a look at the **AND-Operator** (logical conjunction) using a mining-WFS provided by Federal State of Brandenburg.

| Parameter      | Value                                                                                                      |
| -------------- | ---------------------------------------------------------------------------------------------------------- |
| WFS URL        | <https://inspire.brandenburg.de/services/bergbau_wfs?> (mining)                                            |
| Version        | 2.0                                                                                                        |
| Features Types | bgberechtig (mining rights)                                                                                |
| Max Features   | leave blank                                                                                                |
| xmlns          | <p>fes="<http://www.opengis.net/fes/2.0>"<br>app="<http://www.deegree.org/app>"</p>                        |
|                | <p>inhaber (de) = holder (en)<br>bodenschatz\_kurz (de) = resource, abbr. (en)<br>Ton (de) = clay (en)</p> |

First, we want to get all mining rights in Brandenburg owned by the company called "BVVG Bodenverwertungs- und -verwaltungs GmbH".

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:inhaber</fes:ValueReference>
		<fes:Literal>BVVG Bodenverwertungs- und -verwaltungs GmbH</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>
```

The WFS will return 35 polygon features.

Next, we're interested in all clay pits.

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:bodenschatz_kurz</fes:ValueReference>
		<fes:Literal>Ton</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>
```

We will get 29 polygon features.

If we want to see only the clay pits owned by BVVG, we have to put all of this together using the **AND-Operator**.

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
   <fes:And>
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:inhaber</fes:ValueReference>
		<fes:Literal>BVVG Bodenverwertungs- und -verwaltungs GmbH</fes:Literal>
	</fes:PropertyIsEqualTo>
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:bodenschatz_kurz</fes:ValueReference>
		<fes:Literal>Ton</fes:Literal>
	</fes:PropertyIsEqualTo>
   </fes:And>
</fes:Filter>
```

The WFS will return 7 polygon features.

## Good to know #4

You may ask yourself: is it possible to combine both

1. Comparison Operators
2. Spatial Operators

???

The answer is: yes, it is possible!

To demonstrate it, just copy the **BBOX-Expression** from [Spatial Operators](/filter-expressions-in-fme/spatial-operators.md#bbox)

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:gml="http://www.opengis.net/gml/3.2">
  <fes:BBOX>
        <gml:Envelope srsName="urn:ogc:def:crs:EPSG::25832">
          <gml:lowerCorner>367441.62 5620100.532</gml:lowerCorner>
          <gml:upperCorner>367619.15 5620254.767</gml:upperCorner>
       </gml:Envelope>
   </fes:BBOX>
</fes:Filter>
```

Next, create a **PropertyIsLike-Expression** like this

```xml
<fes:Filter 
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:cp="http://inspire.ec.europa.eu/schemas/cp/4.0">
   <fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
      <fes:ValueReference>cp:nationalCadastralReference</fes:ValueReference>
      <fes:Literal>054302026*</fes:Literal>
   </fes:PropertyIsLike>
</fes:Filter>
```

Check, if both expressions are running stand-alone.

If so, please combine them using the **AND-Operator**:

```xml
<fes:Filter 
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:cp="http://inspire.ec.europa.eu/schemas/cp/4.0">
   <fes:And>
   <fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
      <fes:ValueReference>cp:nationalCadastralReference</fes:ValueReference>
      <fes:Literal>054302026*</fes:Literal>
   </fes:PropertyIsLike>
   <fes:BBOX>
        <gml:Envelope srsName="urn:ogc:def:crs:EPSG::25832">
          <gml:lowerCorner>367441.62 5620100.532</gml:lowerCorner>
          <gml:upperCorner>367619.15 5620254.767</gml:upperCorner>
       </gml:Envelope>
   </fes:BBOX>
   </fes:And>
</fes:Filter>
```

What's the difference?

See for yourself!

<figure><img src="/files/FrPCx8f51EjMMwwpmt6i" alt=""><figcaption><p>Original BBOX</p></figcaption></figure>

<figure><img src="/files/EUCJ0Cse1Pdwu8axGUQB" alt=""><figcaption><p>BBOX combined with attribute filter</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://olivers-expression-lab.gitbook.io/filter-expressions-in-fme/logical-operators.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
