# Source: https://content.nuxt.com/raw/docs/utils/query-collection.md

# queryCollection

> The queryCollection composable provides methods for querying and fetching your collections.

## Usage

Use the auto-imported `queryCollection` to find contents inside a collection. Here we assume that you have defined `docs` collection inside `content.config.ts`.

If you have not defined any collection, check [How to define a collection](/docs/collections/define#defining-collections).

```vue [pages/[...slug].vue]
<script setup>
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
  return queryCollection('docs').path(route.path).first()
})
</script>
```

<tip>

The `queryCollection` utility is available in both Vue and Nitro. Checkout [Server Usage](#server-usage) for more details on how to use it on the server side.

</tip>

## API

### Type

```ts
function queryCollection<T extends keyof Collections>(collection: T): CollectionQueryBuilder<Collections[T]>

interface CollectionQueryBuilder<T> {
  where(field: keyof T | string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<T>
  andWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>
  orWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>
  order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder<T>
  // ... other methods
}
```

### `queryCollection(collection: CollectionName)`

Create a query builder to search in the specific collection.

- Parameter:

  - `collection`: The key of defined collection in `content.config.ts`

### `path(path: string)`

Search for contents that have specific `path`. (`path` is an special field in `page` collections which generates based on fs path and can be use as route to render the content)

- Parameter:

  - `path`: The path string to match.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs').path(route.path).first()
})
```

### `select(...fields: keyof Collection)`

Select specific fields from the collection to be returned in the query result.

- Parameters:

  - `...fields`: A list of field names to select from the collection.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    .select('path', 'title', 'description')
    .first()
})
```

### `where(field: keyof Collection | string, operator: SqlOperator, value?: unknown)`

Add a condition to the query to filter results based on a specific field.

- Parameters:

  - `field`: The field to filter on
  - `operator`: The SQL operator to use for comparison. Possible values include:
  
    - `'='`: Equal to
    - `'>'`: Greater than
    - `'<'`: Less than
    - `'<>'`: Not equal to
    - `'IN'`: In a list of values
    - `'BETWEEN'`: Between two values
    - `'NOT BETWEEN'`: Not between two values
    - `'IS NULL'`: Is null
    - `'IS NOT NULL'`: Is not null
    - `'LIKE'`: Matches a pattern
    - `'NOT LIKE'`: Does not match a pattern
  - `value`: The value to compare against. The type depends on the operator used.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    .where('date', '<', '2024-04-04')
    .where('category', '=', 'news')
    .all()
})

// Generated SQL
// SELECT * FROM docs WHERE date < '2024-04-04' AND category = 'news'
```

### `andWhere(groupFactory: QueryGroupFunction<Collection>)`

Add an AND condition group to the query. This allows for more complex query conditions.

- Parameter:

  - `groupFactory`: A function that receives a query builder and can add multiple conditions that will be grouped together with AND

```ts
const { data } = await useAsyncData('recent-docs', () => {
  return queryCollection('docs')
    .where('published', '=', true)
    .andWhere(query => query.where('date', '>', '2024-01-01').where('category', '=', 'news'))
    .all()
})

// Generated SQL
// SELECT * FROM docs WHERE published = true AND (date > '2024-01-01' AND category = 'news')
```

### `orWhere(groupFactory: QueryGroupFunction<Collection>)`

Add an OR condition group to the query. This allows for alternative conditions.

- Parameter:

  - `groupFactory`: A function that receives a query builder and can add multiple conditions that will be grouped together with OR

```ts
const { data } = await useAsyncData('featured-docs', () => {
  return queryCollection('docs')
    .where('published', '=', true)
    .orWhere(query => query.where('featured', '=', true).where('priority', '>', 5))
    .all()
})

// Generated SQL
// SELECT * FROM docs WHERE published = true AND (featured = true OR priority > 5)
```

### `order(field: keyof Collection, direction: 'ASC' | 'DESC')`

Order the query results based on a specific field.

- Parameters:

  - `field`: The field to order by.
  - `direction`: The direction of ordering, either 'ASC' for ascending or 'DESC' for descending.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    .order('date', 'DESC')
    .all()
})
```

### `limit(limit: number)`

Limit the number of results returned by the query.

- Parameter:

  - `limit`: The maximum number of results to return.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    .limit(10)
    .all()
})
```

### `skip(skip: number)`

Skip a specified number of results in the query.

- Parameter:

  - `skip`: The number of results to skip.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    // Skip first 5 items
    .skip(5)
    .all()
})
```

### `all()`

Execute the query and return all matching results.

- Returns: A Promise that resolves to an array of all matching documents.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs').all()
})
```

### `first()`

Execute the query and return the first matching result.

- Returns: A Promise that resolves to the first matching document, or `null` if no documents match.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs').first()
})
```

### `count()`

Count the number of matched collection entries based on the query.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    // Count matches
    .count()
})

// Returns
5 // number of matches
```

You can also use `count()` with other methods defined above such as `where()` in order to apply additional conditions within the collection query.

```ts
const route = useRoute()
const { data } = await useAsyncData(route.path, () => {
  return queryCollection('docs')
    .where('date', '<', '2024-04-04')
    // Count matches
    .count()
})

// Returns
3 // number of matches for the provided query
```

## Examples

Here is a complete example of how to fetch a list of documents in the `docs` collections.

```vue [index.vue]
<script setup lang="ts">
const { data: docs } = await useAsyncData('documents-list', () => {
  return queryCollection('docs')
    .order('date', 'DESC')
    .select('title', 'path', 'description')
    .all()
})
</script>

<template>
  <NuxtLink v-for="doc in docs" :key="doc.path" :to="doc.path">
    <h2>{{ doc.title }}</h2>
    <p>{{ doc.description }}</p>
  </NuxtLink>
</template>
```

## Server Usage

Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass `event` as the first argument to the `queryCollection` function.

```ts [server/api/[slug].ts]
export default eventHandler(async (event) => {
  const { slug } = getRouterParams(event)
  const page = await queryCollection(event, 'docs').path(slug).first()
  return page
})
```

<note>

Make sure to create `server/tsconfig.json` file with the following content to avoid type error.

```json
{
  "extends": "../.nuxt/tsconfig.server.json"
}
```

</note>