add full text search

This commit is contained in:
lovasoa
2025-05-07 01:50:04 +02:00
parent f5730354fb
commit d526ccbc01
5 changed files with 131 additions and 9 deletions
+9 -7
View File
@@ -104,9 +104,9 @@ SET var = (SELECT * FROM t);
-- now $var contains '1'
```
Temporary table-valued results can be stored in two ways:
Temporary table-valued results can be stored in two ways.
1. Using temporary tables
## Storing large datasets in the database with temporary tables
This is the most efficient method to store large values.
```sql
@@ -122,12 +122,13 @@ INSERT INTO my_temp_table(a, b)
VALUES (1, 2), (3, 4);
```
2. Using JSON
## Storing rich structured data in memory using JSON
This can be more convenient, but should only be used for small values, because data
is copied from the database into SQLPage memory, and to the database again at each use.
You can use the [JSON functions from your database](/blog.sql?post=JSON in SQL%3A A Comprehensive Guide).
You can use the [JSON functions from your database](/blog.sql?post=JSON+in+SQL%3A+A+Comprehensive+Guide).
Here are some examples with SQLite:
```sql
-- CREATE TABLE my_table(a, b);
@@ -151,7 +152,7 @@ See the [functions page](/functions.sql) for more details.
They're either executed before or after the query is run in the database.
### Execution functions *before* sending a query to the database
### Executing functions *before* sending a query to the database
When they don't process results coming from the database:
@@ -161,12 +162,13 @@ SELECT * FROM blog WHERE slug = sqlpage.path()
`sqlpage.path()` will get replaced by the result of the function.
### Execution functions *after* receiving results from the database
### Executing functions *after* receiving results from the database
When they process results coming from the database:
```sql
SELECT sqlpage.read_file_as_text(blog_post_file) AS title FROM blog;
SELECT sqlpage.read_file_as_text(blog_post_file) AS title
FROM blog;
```
The query executed will be:
+1 -1
View File
@@ -6,4 +6,4 @@ select 'dynamic' as component, properties FROM example WHERE component = 'shell'
-- Article by Matthew Larkin
select 'text' as component,
sqlpage.read_file_as_text('extensions-to-sql.md') as contents_md,
false as article;
true as article;
+87
View File
@@ -0,0 +1,87 @@
-- Check for exact matches and redirect if found
set redirect = CASE
WHEN EXISTS (SELECT 1 FROM component WHERE name = $search) THEN sqlpage.link('/component.sql', json_object('component', $search))
WHEN EXISTS (SELECT 1 FROM sqlpage_functions WHERE name = $search) THEN sqlpage.link('/functions.sql', json_object('function', $search))
END
SELECT 'redirect' as component, $redirect as link WHERE $redirect IS NOT NULL;
select 'dynamic' as component, properties FROM example WHERE component = 'shell' LIMIT 1;
SELECT 'form' as component,
'GET' as method,
true as auto_submit,
'Search documentation' as title;
SELECT 'text' as type,
'search' as name,
'' as label,
true as autofocus,
'Search for components, parameters, functions...' as placeholder,
$search as value;
SELECT 'text' as component,
CASE
WHEN $search IS NULL THEN 'Enter a search term above to find documentation about components, parameters, functions, and blog posts.'
WHEN NOT EXISTS (
SELECT 1 FROM documentation_fts
WHERE documentation_fts = $search
) THEN 'No results found for "' || $search || '".'
ELSE NULL
END as contents;
SELECT 'list' as component,
'Search Results' as title,
'No results found for "' || $search || '".' as empty_description
WHERE $search IS NOT NULL;
WITH search_results AS (
SELECT
CASE
WHEN parameter_name IS NOT NULL THEN component_name || ' component: parameter ' || parameter_name
WHEN component_name IS NOT NULL THEN component_name || ' component'
WHEN blog_title IS NOT NULL THEN 'blog: ' || blog_title
WHEN function_parameter_name IS NOT NULL THEN function_name || '(...' || function_parameter_name || '...)'
WHEN function_name IS NOT NULL THEN function_name || '(...)'
END as title,
CASE
WHEN component_description IS NOT NULL THEN component_description
WHEN parameter_description IS NOT NULL THEN parameter_description
WHEN blog_description IS NOT NULL THEN blog_description
WHEN function_description IS NOT NULL THEN function_description
WHEN function_parameter_description IS NOT NULL THEN function_parameter_description
END as description,
CASE
WHEN component_name IS NOT NULL THEN json_object('page', '/component.sql', 'parameters', json_object('component', component_name))
WHEN parameter_name IS NOT NULL THEN json_object('page', '/component.sql', 'parameters', json_object('component', (
SELECT component FROM parameter
WHERE name = parameter_name
LIMIT 1
)))
WHEN blog_title IS NOT NULL THEN json_object('page', '/blog.sql', 'parameters', json_object('post', blog_title))
WHEN function_name IS NOT NULL THEN json_object('page', '/functions.sql', 'parameters', json_object('function', function_name))
WHEN function_parameter_name IS NOT NULL THEN json_object('page', '/functions.sql', 'parameters', json_object('function', (
SELECT function FROM sqlpage_function_parameters
WHERE name = function_parameter_name
LIMIT 1
)))
END as link_data,
rank
FROM documentation_fts
WHERE $search IS NOT NULL
AND documentation_fts = $search
)
SELECT
title,
description,
sqlpage.link(link_data->>'page', link_data->'parameters') as link
FROM search_results
ORDER BY
rank,
CASE
WHEN title LIKE 'component:%' THEN 1
WHEN title LIKE 'parameter:%' THEN 2
WHEN title LIKE 'blog:%' THEN 3
WHEN title LIKE 'function:%' THEN 4
END,
description;
@@ -1244,7 +1244,8 @@ You see the [page layouts demo](./examples/layouts.sql) for a live example of th
{"link": "/extensions-to-sql", "title": "Extensions to SQL", "icon": "cube-plus"},
{"link": "/custom_components.sql", "title": "Custom Components", "icon": "puzzle"},
{"link": "//github.com/sqlpage/SQLPage/blob/main/configuration.md#configuring-sqlpage", "title": "Configuration", "icon": "settings"}
]}
]},
{"title": "Search", "link": "/search"}
],
"layout": "boxed",
"language": "en-US",
@@ -0,0 +1,32 @@
CREATE VIRTUAL TABLE documentation_fts USING fts5(
component_name,
component_description,
parameter_name,
parameter_description,
blog_title,
blog_description,
function_name,
function_description,
function_parameter_name,
function_parameter_description,
component_example_description,
component_example_json
);
INSERT INTO documentation_fts(component_name, component_description)
SELECT name, description FROM component;
INSERT INTO documentation_fts(component_name, parameter_name, parameter_description)
SELECT component, name, description FROM parameter;
INSERT INTO documentation_fts(blog_title, blog_description)
SELECT title, description FROM blog_posts;
INSERT INTO documentation_fts(function_name, function_description)
SELECT name, description_md FROM sqlpage_functions;
INSERT INTO documentation_fts(function_name, function_parameter_name, function_parameter_description)
SELECT function, name, description_md FROM sqlpage_function_parameters;
INSERT INTO documentation_fts(component_name, component_example_description, component_example_json)
SELECT component, description, properties FROM example;