diff --git a/internal/search/datasources/postgres/postgres.go b/internal/search/datasources/postgres/postgres.go
index ebfadd2..a57448f 100644
--- a/internal/search/datasources/postgres/postgres.go
+++ b/internal/search/datasources/postgres/postgres.go
@@ -52,16 +52,17 @@ func (p *Postgres) SearchFeaturesAcrossCollections(ctx context.Context, searchTe
defer cancel()
// Split terms by spaces and append :* to each term
- terms := strings.Fields(searchTerm)
- for i, term := range terms {
- terms[i] = term + ":*"
+ termsWildcard := strings.Fields(searchTerm)
+ for i, term := range termsWildcard {
+ termsWildcard[i] = term + ":*"
}
- termsConcat := strings.Join(terms, " & ")
+ termsWildcardConcat := strings.Join(termsWildcard, " & ")
+ termExactConcat := strings.Join(strings.Fields(searchTerm), " | ")
query := makeSearchQuery(p.searchIndex, srid)
// Execute search query
names, ints := collections.NamesAndVersions()
- rows, err := p.db.Query(queryCtx, query, limit, termsConcat, names, ints)
+ rows, err := p.db.Query(queryCtx, query, limit, termsWildcardConcat, termExactConcat, names, ints)
if err != nil {
return nil, fmt.Errorf("query '%s' failed: %w", query, err)
}
@@ -74,32 +75,66 @@ func (p *Postgres) SearchFeaturesAcrossCollections(ctx context.Context, searchTe
func makeSearchQuery(index string, srid d.SRID) string {
// language=postgresql
query := fmt.Sprintf(`
- with query as (
- select to_tsquery('simple', $2) query
+ WITH query_wildcard AS (
+ SELECT to_tsquery('simple', $2) query
+ ),
+ query_exact AS (
+ SELECT to_tsquery('simple', $3) query
)
- select r.display_name as display_name,
- max(r.feature_id) as feature_id,
- max(r.collection_id) as collection_id,
- max(r.collection_version) as collection_version,
- max(r.geometry_type) as geometry_type,
- st_transform(max(r.bbox), %[2]d)::geometry as bbox,
- max(r.rank) as rank,
- max(r.highlighted_text) as highlighted_text
- from (
- select display_name, feature_id, collection_id, collection_version, geometry_type, bbox,
- ts_rank_cd(ts, (select query from query), 1) as rank,
- ts_headline('simple', suggest, (select query from query)) as highlighted_text
- from %[1]s
- where ts @@ (select query from query) and (collection_id, collection_version) in (
- -- make a virtual table by creating tuples from the provided arrays.
- select * from unnest($3::text[], $4::int[])
- )
- order by rank desc, display_name asc -- keep the same as outer 'order by' clause
- limit 500
- ) r
- group by r.display_name, r.collection_id, r.collection_version, r.feature_id
- order by rank desc, display_name asc
- limit $1`, index, srid) // don't add user input here, use $X params for user input!
+ SELECT
+ rn.display_name AS display_name,
+ rn.feature_id AS feature_id,
+ rn.collection_id AS collection_id,
+ rn.collection_version AS collection_version,
+ rn.geometry_type AS geometry_type,
+ st_transform(rn.bbox, %[2]d)::geometry AS bbox,
+ rn.rank AS rank,
+ rn.highlighted_text AS highlighted_text
+ FROM (
+ SELECT
+ *,
+ ROW_NUMBER() OVER (
+ PARTITION BY
+ r.display_name,
+ r.collection_id,
+ r.collection_version,
+ r.feature_id
+ ORDER BY
+ r.rank DESC,
+ r.display_name ASC
+ ) AS row_number
+ FROM (
+ SELECT
+ display_name,
+ feature_id,
+ collection_id,
+ collection_version,
+ geometry_type,
+ bbox,
+ CASE WHEN display_name=suggest THEN
+ ts_rank(ts, (SELECT query FROM query_exact), 1) + 0.01 + ts_rank(ts, (SELECT query FROM query_wildcard), 1)
+ ELSE
+ ts_rank(ts, (SELECT query FROM query_exact), 1) + ts_rank(ts, (SELECT query FROM query_wildcard), 1)
+ END AS rank,
+ ts_headline('simple', suggest, (SELECT query FROM query_wildcard)) AS highlighted_text
+ FROM
+ %[1]s
+ WHERE
+ ts @@ (SELECT query FROM query_wildcard) AND (collection_id, collection_version) IN (
+ -- make a virtual table by creating tuples from the provided arrays.
+ SELECT * FROM unnest($4::text[], $5::int[])
+ )
+ ORDER BY -- keep the same as outer and row_number 'order by' clause
+ rank DESC,
+ display_name ASC
+ LIMIT 500
+ ) r
+ ) rn
+ WHERE rn.row_number = 1
+ ORDER BY
+ rank DESC,
+ display_name ASC
+ LIMIT $1`, index, srid) // don't add user input here, use $X params for user input!
return query
}
diff --git a/internal/search/testdata/expected-search-den-building-collection-wgs84.json b/internal/search/testdata/expected-search-den-building-collection-wgs84.json
index 605f2de..8a7c3e0 100644
--- a/internal/search/testdata/expected-search-den-building-collection-wgs84.json
+++ b/internal/search/testdata/expected-search-den-building-collection-wgs84.json
@@ -19,7 +19,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/51?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -67,7 +67,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/52?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -115,7 +115,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/32183?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -163,7 +163,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/53?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -211,7 +211,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/32184?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -259,7 +259,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/54?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -307,7 +307,7 @@
"displayName": "Abbewaal - Den Burg 11",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/22549?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -355,7 +355,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/56?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -403,7 +403,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/55?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -451,7 +451,7 @@
"displayName": "Abbewaal - Den Burg 15",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/57?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
diff --git a/internal/search/testdata/expected-search-den-multiple-collection-single-output-wgs84.json b/internal/search/testdata/expected-search-den-multiple-collection-single-output-wgs84.json
index 4bd600f..a6ccc67 100644
--- a/internal/search/testdata/expected-search-den-multiple-collection-single-output-wgs84.json
+++ b/internal/search/testdata/expected-search-den-multiple-collection-single-output-wgs84.json
@@ -19,7 +19,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/51?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -67,7 +67,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/52?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -115,7 +115,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/32183?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -163,7 +163,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/53?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -211,7 +211,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/32184?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -259,7 +259,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/54?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -307,7 +307,7 @@
"displayName": "Abbewaal - Den Burg 11",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/22549?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -355,7 +355,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/56?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -403,7 +403,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/55?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -451,7 +451,7 @@
"displayName": "Abbewaal - Den Burg 15",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/57?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -499,7 +499,7 @@
"displayName": "Abbewaal - Den Burg 15",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/58?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -547,7 +547,7 @@
"displayName": "Abbewaal - Den Burg 17",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/16128?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -595,7 +595,7 @@
"displayName": "Abbewaal - Den Burg 19",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/59?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -643,7 +643,7 @@
"displayName": "Abbewaal - Den Burg 19 A",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/23322?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -691,7 +691,7 @@
"displayName": "Abbewaal - Den Burg 2",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/16129?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -739,7 +739,7 @@
"displayName": "Abbewaal - Den Burg 2",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/16130?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -787,7 +787,7 @@
"displayName": "Abbewaal - Den Burg 21",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/60?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -835,7 +835,7 @@
"displayName": "Abbewaal - Den Burg 21 A",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/61?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -883,7 +883,7 @@
"displayName": "Abbewaal - Den Burg 23",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/16132?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -931,7 +931,7 @@
"displayName": "Abbewaal - Den Burg 23",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/buildings/items/16131?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
diff --git a/internal/search/testdata/expected-search-den-single-collection-rd.json b/internal/search/testdata/expected-search-den-single-collection-rd.json
index 7e3753f..469f54e 100644
--- a/internal/search/testdata/expected-search-den-single-collection-rd.json
+++ b/internal/search/testdata/expected-search-den-single-collection-rd.json
@@ -19,7 +19,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/51?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -67,7 +67,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/52?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -115,7 +115,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/32183?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -163,7 +163,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/53?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -211,7 +211,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/32184?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -259,7 +259,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/54?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -307,7 +307,7 @@
"displayName": "Abbewaal - Den Burg 11",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/22549?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -355,7 +355,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/56?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -403,7 +403,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/55?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -451,7 +451,7 @@
"displayName": "Abbewaal - Den Burg 15",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/57?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
diff --git a/internal/search/testdata/expected-search-den-single-collection-wgs84.json b/internal/search/testdata/expected-search-den-single-collection-wgs84.json
index f0b5693..6eb05e8 100644
--- a/internal/search/testdata/expected-search-den-single-collection-wgs84.json
+++ b/internal/search/testdata/expected-search-den-single-collection-wgs84.json
@@ -19,7 +19,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/51?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -67,7 +67,7 @@
"displayName": "Abbewaal - Den Burg 1",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/52?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -115,7 +115,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/32183?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -163,7 +163,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/53?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -211,7 +211,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/32184?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -259,7 +259,7 @@
"displayName": "Abbewaal - Den Burg 10",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/54?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -307,7 +307,7 @@
"displayName": "Abbewaal - Den Burg 11",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/22549?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -355,7 +355,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/56?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -403,7 +403,7 @@
"displayName": "Abbewaal - Den Burg 13",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/55?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",
@@ -451,7 +451,7 @@
"displayName": "Abbewaal - Den Burg 15",
"highlight": "Abbewaal Den Burg",
"href": "https://example.com/ogc/v1/collections/addresses/items/57?f=json",
- "score": 0.07213475555181503
+ "score": 0.0607927106320858
},
"geometry": {
"type": "Polygon",