Skip to content

Commit

Permalink
Merge pull request #12 from qwc-services/search_doc
Browse files Browse the repository at this point in the history
Add initial search documentation for solr + fulltext search
  • Loading branch information
manisandro authored Oct 12, 2023
2 parents 6a01385 + 86dd055 commit f09cd6e
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
Binary file added src/images/add_solr_search_facet_permission.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/create_solr_search_facet_resource.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/generate_service_configurations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 159 additions & 1 deletion src/topics/Search.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,162 @@ Note: The `qwc2-demo-app` (also used by the `qwc-map-viewer-demo` docker image)

## Configuring the fulltext search service <a name="fulltext-search"></a>

For more information on the full-text search provider, see [qwc-fulltext-search-service](https://github.com/qwc-services/qwc-fulltext-search-service).
### Solr configuration

Before the fulltext search service can be configured,
a new solr configuration file must be created.
This file must be created in `volumes/solr/configsets/gdi/conf/`.
The name of the file can be chosen freely.
Here is an example XML file:

```xml
<dataConfig>
<dataSource
driver="org.postgresql.Driver"
url="jdbc:postgresql://{DB_HOST}:{DB_PORT}/{DB_NAME}"
user="{DB_USER}"
password="{DB_PASSWORD}"
/>
<document>
<entity name="{SEARCH_NAME}" query="
WITH index_base AS (
/* ==== Base query for search index ==== */
SELECT
'{SEARCH_NAME}'::text AS subclass,
{PRIMARY_KEY} AS id_in_class,
'{PRIMARY_KEY}' AS id_name,
'{SEARCH_FIELD_DATA_TYPE}:n' AS id_type,
{DISPLAYTEXT} AS displaytext,
{SEARCH_FIELD_1} AS search_part_1,
{GEOMETRY_FIELD} AS geom
FROM {SCHEMA}.{SEARCH_TABLE_NAME}
/* ===================================== */
)
SELECT
(array_to_json(array_append(ARRAY[subclass::text], id_in_class::text)))::text AS id,
displaytext AS display,
search_part_1 AS search_1_stem,
search_part_1 AS sort,
subclass AS facet,
'default' AS tenant,
(array_to_json(array_append(ARRAY[id_name::text], id_type::text)))::text AS idfield_meta,
(st_asgeojson(st_envelope(geom), 0, 1)::json -> 'bbox')::text AS bbox
FROM index_base">
</entity>
</document>
</dataConfig>
```

The next table shows how the values, that are surrounded by `{}`, need to be defined.

| **Name** | **Definition** | **Example** |
|--------------------------|-----------------------------------------------------------------------------------|------------------|
| `DB_HOST` | Database hostname | `qwc-postgis` |
| `DB_NAME` | Database name | `qwc_demo` |
| `DB_PORT` | Database port number | `5432` |
| `DB_USER` | Database username | `qwc_service` |
| `DB_PASSWORD` | Password for the specified database user | `qwc_service` |
| `SEARCH_NAME` | Name of the search | `fluesse_search` |
| `PRIMARY_KEY` | Primary key name of the table that is used in the search query | `ogc_fid` |
| `SEARCH_FIELD_DATA_TYPE` | Search field data type | `str` |
| `DISPLAYTEXT` | Displaytext that will be shown by the QWC2 when a match was found | `name_long` |
| `SEARCH_FIELD_1` | Table field that will be used by the search | `name_long` |
| `GEOMETRY_FIELD` | Name of the geometry column of the search table | `wkb_geometry` |
| `SCHEMA` | Search table schema | `qwc_geodb` |
| `SEARCH_TABLE_NAME` | Search table name | `fluesse` |

*IMPORTANT*:
In the case of several searches sharing the same database connection,
all searche queries can be written to the same XML file. Each search
corresponds to exactly one <entity> tag in the XML file.

After the configuration file has been created, the search must be registered in `solr`.
In the `volumes/solr/configsets/gdi/conf/solrconfig.xml` file you have to look for
`<!-- SearchHandler` and add the following configuration

```xml
<requestHandler name="/SEARCH_NAME" class="solr.DataImportHandler">
<lst name="defaults">
<str name="config">NAME_OF_THE_CONFIGURATION_FILE.xml</str>
</lst>
</requestHandler>
```

At last, the `solr` index has to be generated:

```
rm -rf volumes/solr/data/*
docker compose restart qwc-solr
curl 'http://localhost:8983/solr/gdi/SEARCH_NAME?command=full-import'
```

### Configure fulltext service

The configuration of the fulltext search service can be found in `tenantConfig.json`.
Search the `services` list for the JSON object that has `search` as its name.
Then add a new facet to the facets list. An example entry could be:

```json
{
"name": "search",
"config": {
"solr_service_url": "http://qwc-solr:8983/solr/gdi/select",
"search_result_limit": 50,
"db_url": "postgresql:///?service=qwc_geodb"
},
"resources": {
"facets": [
{
"name": "SEARCH_NAME",
"filter_word": "OPTIONAL_SEARCH_FILTER",
"table_name": "SCHEMA.SEARCH_TABLE_NAME",
"geometry_column": "GEOMETRY_FIELD",
"search_id_col": "PRIMARY_KEY"
}
]
}
}
```

The `filter_word` field can be specified to activate / deactivate searches,
if you have configure multiple searches for one theme.
Normally `filter_word` is left empty (`""`) which results in the search always
being active.
But if specified (e.g. `"house_no"` then the fulltext search will only use
the configured search, if the user prefixes his search choise with "house_no:".

### Activate search for a map

In the last step, you only have to activate the search for a specific topic
and give the users the necessary rights in the Admin GUI.

1. Add the following to a theme item in the `themesConfig`:

```json
"searchProviders": [
{
"provider": "solr",
"default": [],
"layers": {
"QGIS_LAYER": "SEARCH_NAME"
}
}
]
```

When activating a search to a theme, you can either:

* Add the search name to the `default` list, where it is always active
* Add the search name to the `layers` object, where it is only active if the QGIS layer called `QGIS_LAYER` is present on the map

2. Create a new resource in the Admin GUI

![Create resource](../images/create_solr_search_facet_resource.png?style=centerme)

3. Add permissions on the newly created resource

![Add permission](../images/add_solr_search_facet_permission.png?style=centerme)

4. Re-generate the services configurations with the `Generate service configuration` button

![Generate service configurations](../images/generate_service_configurations.png?style=centerme)

0 comments on commit f09cd6e

Please sign in to comment.