Skip to content

Commit 3d55b0a

Browse files
committed
docs: update query builder docs
1 parent c9a0cda commit 3d55b0a

File tree

3 files changed

+194
-44
lines changed

3 files changed

+194
-44
lines changed

docs/content/docs/3.utils/1.query-collection.md

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@ const { data: page } = await useAsyncData(route.path, () => {
2626

2727
```ts
2828
function queryCollection<T extends keyof Collections>(collection: T): CollectionQueryBuilder<Collections[T]>
29-
```
3029

30+
interface CollectionQueryBuilder<T> {
31+
where(field: keyof T | string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<T>
32+
andWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>
33+
orWhere(groupFactory: QueryGroupFunction<T>): CollectionQueryBuilder<T>
34+
order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder<T>
35+
// ... other methods
36+
}
37+
```
3138

3239
### `queryCollection(collection: CollectionName)`
3340

@@ -66,6 +73,73 @@ const { data } = await useAsyncData(route.path, () => {
6673
})
6774
```
6875

76+
### `where(field: keyof Collection | string, operator: SqlOperator, value?: unknown)`
77+
78+
Add a condition to the query to filter results based on a specific field.
79+
80+
- Parameters:
81+
- `field`: The field to filter on
82+
- `operator`: The SQL operator to use for comparison. Possible values include:
83+
- `'='`: Equal to
84+
- `'>'`: Greater than
85+
- `'<'`: Less than
86+
- `'<>'`: Not equal to
87+
- `'in'`: In a list of values
88+
- `'BETWEEN'`: Between two values
89+
- `'NOT BETWEEN'`: Not between two values
90+
- `'IS NULL'`: Is null
91+
- `'IS NOT NULL'`: Is not null
92+
- `'LIKE'`: Matches a pattern
93+
- `'NOT LIKE'`: Does not match a pattern
94+
- `value`: The value to compare against. The type depends on the operator used.
95+
96+
```ts
97+
const route = useRoute()
98+
const { data } = await useAsyncData(route.path, () => {
99+
return queryCollection('docs')
100+
.where('date', '<', '2024-04-04')
101+
.all()
102+
})
103+
```
104+
105+
### `andWhere(groupFactory: QueryGroupFunction<Collection>)`
106+
107+
Add an AND condition group to the query. This allows for more complex query conditions.
108+
109+
- Parameter:
110+
- `groupFactory`: A function that receives a query builder and can add multiple conditions that will be grouped together with AND
111+
112+
```ts
113+
const { data } = await useAsyncData('recent-docs', () => {
114+
return queryCollection('docs')
115+
.where('published', '=', true)
116+
.andWhere(query => {
117+
query.where('date', '>', '2024-01-01')
118+
.where('category', '=', 'news')
119+
})
120+
.all()
121+
})
122+
```
123+
124+
### `orWhere(groupFactory: QueryGroupFunction<Collection>)`
125+
126+
Add an OR condition group to the query. This allows for alternative conditions.
127+
128+
- Parameter:
129+
- `groupFactory`: A function that receives a query builder and can add multiple conditions that will be grouped together with OR
130+
131+
```ts
132+
const { data } = await useAsyncData('featured-docs', () => {
133+
return queryCollection('docs')
134+
.where('published', '=', true)
135+
.orWhere(query => {
136+
query.where('featured', '=', true)
137+
.where('priority', '>', 5)
138+
})
139+
.all()
140+
})
141+
```
142+
69143
### `order(field: keyof Collection, direction: 'ASC' | DESC)`
70144

71145
Order the query results based on a specific field.
@@ -101,8 +175,6 @@ const { data } = await useAsyncData(route.path, () => {
101175

102176
### `skip(skip: number)`
103177

104-
### `skip(skip: number)`
105-
106178
Skip a specified number of results in the query.
107179

108180
- Parameter:
@@ -118,38 +190,8 @@ const { data } = await useAsyncData(route.path, () => {
118190
})
119191
```
120192

121-
### `where(field: keyof Collection, operator: SqlOperator, value?: unkown)`
122-
123-
Add a condition to the query to filter results based on a specific field.
124-
125-
- Parameters:
126-
- `field`: The field to filter on.
127-
- `operator`: The SQL operator to use for comparison. Possible values include:
128-
- `'='`: Equal to
129-
- `'>'`: Greater than
130-
- `'<'`: Less than
131-
- `'<>'`: Not equal to
132-
- `'in'`: In a list of values
133-
- `'BETWEEN'`: Between two values
134-
- `'NOT BETWEEN'`: Not between two values
135-
- `'IS NULL'`: Is null
136-
- `'IS NOT NULL'`: Is not null
137-
- `'LIKE'`: Matches a pattern
138-
- `'NOT LIKE'`: Does not match a pattern
139-
- `value`: The value to compare against. The type depends on the operator used.
140-
141-
```ts
142-
const route = useRoute()
143-
const { data } = await useAsyncData(route.path, () => {
144-
return queryCollection('docs')
145-
.where('date', '<', '2024-04-04')
146-
.all()
147-
})
148-
```
149-
150193
### `all()`
151194

152-
153195
Execute the query and return all matching results.
154196

155197
- Returns: A Promise that resolves to an array of all matching documents.
@@ -161,10 +203,8 @@ const { data } = await useAsyncData(route.path, () => {
161203
})
162204
```
163205

164-
165206
### `first()`
166207

167-
168208
Execute the query and return the first matching result.
169209

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

docs/content/docs/3.utils/2.query-collection-navigation.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,31 @@ description: 'The queryCollectionNavigation composable generates the navigation
66
## Type
77

88
```ts
9-
function queryCollectionNavigation<T extends keyof PageCollections>(collection: T, fields?: Array<keyof PageCollections[T]>): Promise<ContentNavigationItem[]>
9+
function queryCollectionNavigation<T extends keyof PageCollections>(
10+
collection: T,
11+
fields?: Array<keyof PageCollections[T]>
12+
): ChainablePromise<T, ContentNavigationItem[]>
13+
14+
interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
15+
where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
16+
andWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
17+
orWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
18+
order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
19+
}
1020
```
1121

1222
## Usage
1323

1424
Use the auto-imported `queryCollectionNavigation` to generate a navigation tree for a specific collection. This is particularly useful for creating dynamic navigation menus or sidebars based on your content structure.
1525

26+
The function returns a chainable promise that allows you to add additional query conditions:
1627

1728
```vue [pages/[...slug\\].vue]
1829
<script setup lang="ts">
1930
const { data } = await useAsyncData('navigation', () => {
2031
return queryCollectionNavigation('docs')
32+
.where('published', '==', true)
33+
.order('date', 'DESC')
2134
})
2235
</script>
2336
```
@@ -32,6 +45,59 @@ Generate a navigation tree for the specified collection.
3245
- `collection`: The key of the defined collection in `content.config.ts`.
3346
- `extraFields`: (Optional) An array of additional fields to include in the navigation items. (By default `title` and `path` are included in the navigation items.)
3447

35-
- Returns: A Promise that resolves to a navigation tree structure.
48+
- Returns: A chainable promise that resolves to a navigation tree structure. The promise includes methods for adding query conditions:
49+
- `where(field, operator, value)`: Add a WHERE condition
50+
- `andWhere(groupFactory)`: Add a grouped AND condition
51+
- `orWhere(groupFactory)`: Add a grouped OR condition
52+
- `order(field, direction)`: Add an ORDER BY clause
3653

3754
The navigation tree is generated based on the directory structure and ordering happens based on files [ordering](/docs/collections/types#ordering-files)
55+
56+
## Examples
57+
58+
Basic usage without additional query conditions:
59+
60+
```vue [pages/[...slug].vue]
61+
<script setup lang="ts">
62+
const { data } = await useAsyncData('navigation', () => {
63+
return queryCollectionNavigation('docs')
64+
})
65+
</script>
66+
67+
<template>
68+
<nav>
69+
<ul v-if="data">
70+
<li v-for="item in data" :key="item.path">
71+
<NuxtLink :to="item.path">{{ item.title }}</NuxtLink>
72+
</li>
73+
</ul>
74+
</nav>
75+
</template>
76+
```
77+
78+
Example with additional query conditions and extra fields:
79+
80+
```vue [pages/[...slug].vue]
81+
<script setup lang="ts">
82+
const { data } = await useAsyncData('navigation', () => {
83+
return queryCollectionNavigation('docs', ['description', 'badge'])
84+
.where('draft', '==', false)
85+
.where('partial', '==', false)
86+
.order('title', 'ASC')
87+
})
88+
</script>
89+
90+
<template>
91+
<nav>
92+
<ul v-if="data">
93+
<li v-for="item in data" :key="item.path">
94+
<NuxtLink :to="item.path">
95+
{{ item.title }}
96+
<span v-if="item.badge" class="badge">{{ item.badge }}</span>
97+
</NuxtLink>
98+
<p v-if="item.description">{{ item.description }}</p>
99+
</li>
100+
</ul>
101+
</nav>
102+
</template>
103+
```

docs/content/docs/3.utils/3.query-collection-item-surroundings.md

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,32 @@ description: 'The queryCollectionItemSurroundings composable looks for sibling c
66
## Type
77

88
```ts
9-
function queryCollectionItemSurroundings<T extends keyof PageCollections>(collection: T, path: string, opts?: SurroundOptions<keyof PageCollections[T]>): Promise<ContentNavigationItem[]>
9+
function queryCollectionItemSurroundings<T extends keyof PageCollections>(
10+
collection: T,
11+
path: string,
12+
opts?: SurroundOptions<keyof PageCollections[T]>
13+
): ChainablePromise<T, ContentNavigationItem[]>
14+
15+
interface ChainablePromise<T extends keyof PageCollections, R> extends Promise<R> {
16+
where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise<T, R>
17+
andWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
18+
orWhere(groupFactory: QueryGroupFunction<PageCollections[T]>): ChainablePromise<T, R>
19+
order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise<T, R>
20+
}
1021
```
1122

1223
## Usage
1324

1425
Use the auto-imported `queryCollectionItemSurroundings` to find the previous and next items relative to a specific content item in a collection. This is particularly useful for creating navigation between related content pages.
1526

16-
```vue [pages/[...slug\\].vue]
27+
The function returns a chainable promise that allows you to add additional query conditions:
28+
29+
```vue [pages/[...slug].vue]
1730
<script setup lang="ts">
1831
const { data } = await useAsyncData('surround', () => {
1932
return queryCollectionItemSurroundings('docs', '/foo')
33+
.where('published', '==', true)
34+
.order('date', 'DESC')
2035
})
2136
</script>
2237
```
@@ -35,16 +50,42 @@ Find the surrounding items (previous and next) for a specific content item in a
3550
- `after`: (Optional) The number of items to fetch after the current item. Default is 1.
3651
- `fields`: (Optional) An array of additional fields to include in the surrounding items.
3752

38-
- Returns: A Promise that resolves to an array containing the surrounding items. The array will have the following structure:
39-
- `[previousItem, nextItem]` if using default options.
40-
- `[...previousItems, ...nextItems]` if using custom `before` and `after` values.
53+
- Returns: A chainable promise that resolves to an array containing the surrounding items. The promise includes methods for adding query conditions:
54+
- `where(field, operator, value)`: Add a WHERE condition
55+
- `andWhere(groupFactory)`: Add a grouped AND condition
56+
- `orWhere(groupFactory)`: Add a grouped OR condition
57+
- `order(field, direction)`: Add an ORDER BY clause
58+
59+
The final result will be an array with the following structure:
60+
- `[previousItem, nextItem]` if using default options
61+
- `[...previousItems, ...nextItems]` if using custom `before` and `after` values
4162

4263
Each item in the array is of type `ContentNavigationItem` or `null` if there is no item in that position.
4364

44-
## Example
65+
## Examples
4566

46-
Here's an example of how to use `queryCollectionItemSurroundings` to create a simple navigation between content pages:
67+
Basic usage without additional query conditions:
68+
69+
```vue [pages/[...slug].vue]
70+
<script setup lang="ts">
71+
const { data } = await useAsyncData('surround', () => {
72+
return queryCollectionItemSurroundings('docs', '/foo')
73+
})
74+
</script>
75+
76+
<template>
77+
<div class="flex justify-between">
78+
<NuxtLink v-if="data?.[0]" :to="data[0]._path">
79+
← {{ data[0].title }}
80+
</NuxtLink>
81+
<NuxtLink v-if="data?.[1]" :to="data[1]._path">
82+
{{ data[1].title }} →
83+
</NuxtLink>
84+
</div>
85+
</template>
86+
```
4787

88+
Example with additional query conditions:
4889

4990
```vue [pages/[...slug\\].vue]
5091
<script setup lang="ts">
@@ -54,6 +95,9 @@ const { data } = await useAsyncData('surround', () => {
5495
after: 1,
5596
fields: ['badge', 'description']
5697
})
98+
.where('_draft', '==', false)
99+
.where('_partial', '==', false)
100+
.order('date', 'DESC')
57101
})
58102
</script>
59103
```

0 commit comments

Comments
 (0)