
## Compound queries

URL: https://docs.atlan.com/product/capabilities/build-apps/sdks/python/search/references/queries/compound

> Build compound queries with the Atlan Python SDK (pyatlan) to combine multiple search conditions with boolean logic.

# Compound queries

Compound queries[^1] wrap other queries to either:

- Combine their results
- Change their behavior
- Switch query contexts (in particular, from [query](https://docs.atlan.com/llms/platform/python/queries/llms.txt) to [filter](https://docs.atlan.com/llms/platform/python/queries/llms.txt) context)

In other words, you can use compound queries to *combine* any number of [term-level](https://docs.atlan.com/llms/platform/python/term-level/llms.txt) and [full-text](https://docs.atlan.com/llms/platform/python/full-text/llms.txt) queries (and in fact other compound queries as well).

> *Details — see full content on the documentation site.*

## Bool

[Bool queries](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) combine multiple queries using `must`, `should`, `must_not` and `filter` clauses. These allow you to combine queries with logic like `AND`, `OR` and `NOT`.

| Clause | Description | Context |
|---|---|---|
| `must` | Query clauses must match the results, and will contribute to the score. These act like a logical `AND` operation. | [query](https://docs.atlan.com/llms/platform/python/queries/llms.txt) |
| `should` | Query clauses should match the results, and will contribute to the score. These act like a logical `OR` operation. | [query](https://docs.atlan.com/llms/platform/python/queries/llms.txt) |
| `must_not` | Query clauses must *not* match the results, and are used to either include or exclude results (no scoring). These act like a logical `NOT` operation. | [filter](https://docs.atlan.com/llms/platform/python/queries/llms.txt) |
| `filter` | Query clauses must match the results, but will *not* contribute to the score. | [filter](https://docs.atlan.com/llms/platform/python/queries/llms.txt) |

:::tip[Fluent search uses filter context exclusively]
Note that the `where` clause in fluent search is actually translated to a `filter` clause, and not a `must` clause. Therefore, fluent search exclusively uses [filter](https://docs.atlan.com/llms/platform/python/queries/llms.txt) context. If you truly want to use [query](https://docs.atlan.com/llms/platform/python/queries/llms.txt) context you will need to construct your queries using lower-level Elastic queries rather than fluent search's clauses.
:::
For example, this query would find all active (non-archived) tables with either a classification or a term assigned:

### Java

```java showLineNumbers title="Build the query and request"
IndexSearchRequest index = Table.select(client) // (1)
 .whereSome(Asset.ATLAN_TAGS.hasAnyValue()) // (2)
 .whereSome(Asset.ASSIGNED_TERMS.hasAnyValue())
 .minSomes(1) // (3)
 .toRequest(); // (4)
```

1. You can build up a compound query progressively, starting from the type of asset you want to query using the `select()` method. This will start a query that narrows results to only active assets of this type (`Table` in this example). Because this operation may retrieve information from Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
2. You can add any number of conditions where some of them must match using the `whereSome()` helper with a query as a condition. (You can add any number of _mandatory_ conditions using the `where()` helper with a query as a condition, instead.) Each query you provide can either be from a helper (like these examples) or a full-fledged Elastic `Query`, if you need ultimate flexibility.
3. You can specify how many of these `whereSome()` conditions must match using the `minSomes()` helper.
4. Finally, you can build the compound query into a search request using the `toRequest()` helper method.

### Python

```python showLineNumbers title="Build the query and request"
from pyatlan.model.fluent_search import CompoundQuery, FluentSearch
from pyatlan.model.assets import Table
from pyatlan.client.atlan import AtlanClient

client = AtlanClient()

index = (FluentSearch() # (1)
 .where(CompoundQuery.asset_type(Table)) # (2)
 .where(CompoundQuery.active_assets())
 .where_some(CompoundQuery.tagged(client=client, directly=True)) # (3)
 .where_some(CompoundQuery.assigned_term())
 .min_somes(1) # (4)
 ).to_request() # (5)
```

1. You can build up a compound query progressively by creating a `FluentSearch()` object and chaining conditions onto it.
2. You can add any number of mandatory conditions using the `where()` helper with a query as a condition. You can use query helpers (like these examples from `CompoundQuery` to narrow to assets of a particular type (`Table`) and only active assets), or full-fledged Elastic `Query`'s.
3. You can add any number of conditions where some of them must match using the `where_some()` helper with a query as a condition.
4. You can specify how many of these `where_some()` conditions must match using the `min_somes()` helper.
5. Finally, you can build the compound query into a search request using the `to_request()` helper method.

### Kotlin

```kotlin showLineNumbers title="Build the query and request"
val index = Table.select(client) // (1)
 .whereSome(Asset.ATLAN_TAGS.hasAnyValue()) // (2)
 .whereSome(Asset.ASSIGNED_TERMS.hasAnyValue())
 .minSomes(1) // (3)
 .toRequest() // (4)
```

1. You can build up a compound query progressively, starting from the type of asset you want to query using the `select()` method. This will start a query that narrows results to only active assets of this type (`Table` in this example). Because this operation may retrieve information from Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
2. You can add any number of conditions where some of them must match using the `whereSome()` helper with a query as a condition. (You can add any number of _mandatory_ conditions using the `where()` helper with a query as a condition, instead.) Each query you provide can either be from a helper (like these examples) or a full-fledged Elastic `Query`, if you need ultimate flexibility.
3. You can specify how many of these `whereSome()` conditions must match using the `minSomes()` helper.
4. Finally, you can build the compound query into a search request using the `toRequest()` helper method.

### Raw REST API

```json showLineNumbers title="POST /api/meta/search/indexsearch"
{
 "dsl": {
 "query": {
 "bool": {
 "must": {
 "term": { "__state": { "value": "ACTIVE" }}
 },
 "filter": {
 "term": { "__typeName.keyword": { "value": "Table" }}
 },
 "should": [
 "exists": { "field": "__traitNames" },
 "exists": { "field": "__meanings" }
 ],
 "minimum_should_match": 1
 }
 }
 }
}
```

In the vast majority of cases you will use `bool` queries, which the SDK examples above create. There are other compound query options for influencing scores, but details for these are left to the Elasticsearch documentation linked below.

[^1]: This page is a summary of the details in the Elasticsearch Guide's [Compound queries](https://www.elastic.co/guide/en/elasticsearch/reference/current/compound-queries.html)

---
