Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Locate map pins by indexed WKT #336

Merged
merged 8 commits into from
Sep 17, 2024
Merged

Conversation

ekes
Copy link
Member

@ekes ekes commented Jan 19, 2024

This removes the requirement for an entity load of the geo entity.
It enables the possibility to show multiple locations per directory item as #333.

This removes the requirement for an entity load of the geo entity.
It enables the possibility to show multiple locations per directory
item as #333.
@ekes
Copy link
Member Author

ekes commented Jan 19, 2024

Question: as it's quite good to get rid of those entity loads, should we write an update hook as well? It's presently just new installs.
I'll let people test this first though.

@andybroomfield
Copy link
Contributor

This is the same change BHCC is making to support multiple geo locations for each directory entry.
Would be happy to see this as the default, I do think an update hook would be useful, but needs to be careful not to override customisations (We actully render a teaser display in the map popup).

@finnlewis
Copy link
Member

Tested locally and this works for me.

To test multiple locations on a directory venue, needed to edit the field to allow mutliple.

Got some warnings when enabling the localgov_demo module, like this:

[warning] An overlong value (more than 255 characters) was encountered while indexing: polygon ((1.59335793849 52.72032931532, 1.59333858184 52.72026327369, 1.59335680053 52.72026056323, 1.59321255113 52.71954200457, 1.59400224347 52.71847509411, 1.5940410841 52.71843507181, 1.59502740073 52.71708533155, 1.5950879918 52.71701434594, 1.59093.<br />Database search servers currently cannot index such values correctly – the value was therefore trimmed to the allowed length.

Is that something we want to look at?

@ekes
Copy link
Member Author

ekes commented Jan 30, 2024

Got some warnings when enabling the localgov_demo module, like this:

[warning] An overlong value (more than 255 characters) was encountered while indexing: polygon ((1.59335793849 52.72032931532, 1.59333858184 52.72026327369, 1.59335680053 52.72026056323, 1.59321255113 52.71954200457, 1.59400224347 52.71847509411, 1.5940410841 52.71843507181, 1.59502740073 52.71708533155, 1.5950879918 52.71701434594, 1.59093.<br />Database search servers currently cannot index such values correctly – the value was therefore trimmed to the allowed length.

Is that something we want to look at?

If the maps with areas are also changing - they will be I think - then yes... because that's what that is. Realistically different storage/display for the areas would be best; but the quickest (config wise, not perforance) might just be changing the field type to accept something huge

@finnlewis
Copy link
Member

@ekes discussing on Merge Tuesday, might be nice to store as geojson...

@ekes
Copy link
Member Author

ekes commented Feb 6, 2024

Got some warnings when enabling the localgov_demo module, like this:

[warning] An overlong value (more than 255 characters) was encountered while indexing: polygon ((1.59335793849 52.72032931532, 1.59333858184 52.72026327369, 1.59335680053 52.72026056323, 1.59321255113 52.71954200457, 1.59400224347 52.71847509411, 1.5940410841 52.71843507181, 1.59502740073 52.71708533155, 1.5950879918 52.71701434594, 1.59093.<br />Database search servers currently cannot index such values correctly – the value was therefore trimmed to the allowed length.

Is that something we want to look at?

If the maps with areas are also changing - they will be I think - then yes... because that's what that is. Realistically different storage/display for the areas would be best; but the quickest (config wise, not perforance) might just be changing the field type to accept something huge

Interestingly because of the way the field is loaded (I'm trying to look if this is leaflet or search_api) it is then grabbing it from the entity.

So for the original context of this issue being able to show results from multiple delta location fields, the fact it indexes nothing, isn't an issue 🤯 So it's an improvement. Keeping it as a string also makes sense, because fulltext tokenizes it etc. and puts it into the fulltext index which we for sure don't want.

Fixes the original requirement. But it isn't then a performance improvement. Doing it from indexed data, and indexed data that's already formatted to json would be for sure a win, but it's also quite some more work. It needs both making sure that the db (it's not a solr problem) will store the length of data (and not handle it as tokenized text) and be sure that leaflet will get it from the search result directly.

@stephen-cox stephen-cox self-requested a review February 13, 2024 12:51
@andybroomfield
Copy link
Contributor

I'm having issues with this branch when I actully try and add a second geo to a directory.
Whilst the map does now get all the geos, the location search no longer functions correctly.
At first it seems to work until I add a second geo and then reindex (possibly not even requiring the reindex, still checking).

The SQL query for the location search gets changed (thanks to dumping a dqm inside search api db).
Originally the query is:

SELECT DISTINCT "t"."item_id" AS "item_id", '1000' AS "score", ST_Distance_Sphere(Point('-0.1400561', '50.8214626'), ST_PointFromText(t.localgov_location)) / 1000 AS "localgov_location__distance"
FROM
{search_api_db_localgov_directories_index_default} "t"
WHERE "t"."localgov_directory_channels" = '21'
HAVING "localgov_location__distance" < '2'

But once a second geo is present, it is changed to:

SELECT DISTINCT "t"."item_id" AS "item_id", '1000' AS "score", ST_Distance_Sphere(Point('-0.1400561', '50.8214626'), ST_PointFromText(t.localgov_location)) / 1000 AS "localgov_location__distance"
FROM
{search_api_db_localgov_directories_index_default} "t"
LEFT OUTER JOIN {search_api_db_localgov_directories_index_default_localgov_loca} "t_2" ON t.item_id = t_2.item_id
WHERE ("t"."localgov_directory_channels" = '21') AND ("t_2"."value" < '2')

@ekes
Copy link
Member Author

ekes commented Feb 22, 2024

I'm having issues with this branch when I actully try and add a second geo to a directory. Whilst the map does now get all the geos, the location search no longer functions correctly. At first it seems to work until I add a second geo and then reindex (possibly not even requiring the reindex, still checking).

Possibly related to this https://www.drupal.org/project/search_api/issues/3353060 ?

@andybroomfield
Copy link
Contributor

Thanks @ekes, do we use those patches? I could try on of them and see if it resolves.

@ekes
Copy link
Member Author

ekes commented Feb 22, 2024

I'll be honest I forgot I'd been working on it till you mentioned it there. So not sure if we did start testing them with LGD, the multivalued field only being an issue here more recently. Testing them, feeding back on the issue, and answering any of Thomas' questions that we can would seem a very good _thing_™ at this point. Sorry I'd forgotten about them.

@andybroomfield
Copy link
Contributor

This is working in terms of the general query, but breaks when facets are present (so no map display as that one has facets whereas I temp took them off the proximity search).

Screenshot 2024-02-22 at 1 43 38 pm

However the query has been updated correcty

SELECT DISTINCT "t"."item_id" AS "item_id", '1000' AS "score", ST_Distance_Sphere(Point('-0.1400561', '50.8214626'), ST_PointFromText(t_2.value)) / 1000 AS "localgov_location__distance"
FROM
{search_api_db_localgov_directories_index_default} "t"
LEFT OUTER JOIN {search_api_db_localgov_directories_index_default_localgov_loca} "t_2" ON t.item_id = t_2.item_id
WHERE "t"."localgov_directory_channels" = '21'
HAVING "localgov_location__distance" < '2'

I'll do a bit more digging and update the d.o issue.

@andybroomfield
Copy link
Contributor

Discovery written up and patch added here https://www.drupal.org/project/search_api/issues/3353060#comment-15459294

@andybroomfield
Copy link
Contributor

andybroomfield commented Feb 23, 2024

Next problem, with the proximity search, now we inlcude the map pins for all locations, the map will show items with pins outside the area if they exist with a location inside the area. Ideally a search should only show map pins inside the area. In the below example we have an entry where it has a location in Brighton and London, so it shows both even with a search for Brighton.

Screenshot 2024-02-23 at 10 55 30 am

@ekes
Copy link
Member Author

ekes commented Feb 27, 2024

Ideally a search should only show map pins inside the area. In the below example we have an entry where it has a location in Brighton and London, so it shows both even with a search for Brighton.

Suggest we make a follow-up issue for this one. It won't be possible to remove them from the search results, because they come from a result - basing it on an index of locations with attached services would be solve it for the map, but would make it different from the results below which are directory entry based, so not work in this case. So either filtering the results post query, or centring the map in JS on the search point leaving the additional result outside the zoom, seem the two best options.

@finnlewis
Copy link
Member

Still hoping for some testing from @stephen-cox and me! @finnlewis

Note: we are using this at Greenwich as a patch.

@finnlewis
Copy link
Member

@andybroomfield confirmed that this is working at BHCC

@stephen-cox was going to test this... might you have a chance to review this week?

@andybroomfield
Copy link
Contributor

Heres the actual errors from running PHPunit against this branch locally

Directory Org (Drupal\Tests\localgov_directories_org\Functional\DirectoryOrg)
✘ Directory venue fields

├ Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for views.view.localgov_directory_channel with the following errors: views.view.localgov_directory_channel:display.embed_map.display_options.style.options.leaflet_popup.view_mode missing schema, views.view.localgov_directory_channel:display.embed_map.display_options.style.options.feature_properties missing schema

╵ /app/web/core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php:98
╵ /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:111
╵ /app/web/core/lib/Drupal/Core/Config/Config.php:229
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:278
╵ /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:486
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:257
╵ /app/web/core/lib/Drupal/Core/Entity/EntityBase.php:354
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:609
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_location/localgov_directories_location.install:47
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleHandler.php:400
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:364
╵ /app/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
╵ /app/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:475
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:561
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:369
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_org/tests/Functional/DirectoryOrgTest.php:101
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

Localgov Integration (Drupal\Tests\localgov_directories_org\Functional\LocalgovIntegration)
✘ Localgov search

├ Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for views.view.localgov_directory_channel with the following errors: views.view.localgov_directory_channel:display.embed_map.display_options.style.options.leaflet_popup.view_mode missing schema, views.view.localgov_directory_channel:display.embed_map.display_options.style.options.feature_properties missing schema

╵ /app/web/core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php:98
╵ /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:111
╵ /app/web/core/lib/Drupal/Core/Config/Config.php:229
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:278
╵ /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:486
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:257
╵ /app/web/core/lib/Drupal/Core/Entity/EntityBase.php:354
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:609
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_location/localgov_directories_location.install:47
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleHandler.php:400
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:364
╵ /app/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
╵ /app/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:475
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:561
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:369
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

Directory Venue (Drupal\Tests\localgov_directories_venue\Functional\DirectoryVenue)
✘ Directory venue fields

├ Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for views.view.localgov_directory_channel with the following errors: views.view.localgov_directory_channel:display.embed_map.display_options.style.options.leaflet_popup.view_mode missing schema, views.view.localgov_directory_channel:display.embed_map.display_options.style.options.feature_properties missing schema

╵ /app/web/core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php:98
╵ /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:111
╵ /app/web/core/lib/Drupal/Core/Config/Config.php:229
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:278
╵ /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:486
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:257
╵ /app/web/core/lib/Drupal/Core/Entity/EntityBase.php:354
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:609
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_location/localgov_directories_location.install:47
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleHandler.php:400
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:364
╵ /app/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
╵ /app/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:475
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:561
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:369
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_venue/tests/src/Functional/DirectoryVenueTest.php:105
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

Localgov Integration (Drupal\Tests\localgov_directories_venue\Functional\LocalgovIntegration)
✘ Localgov search

├ Drupal\Core\Config\Schema\SchemaIncompleteException: Schema errors for views.view.localgov_directory_channel with the following errors: views.view.localgov_directory_channel:display.embed_map.display_options.style.options.leaflet_popup.view_mode missing schema, views.view.localgov_directory_channel:display.embed_map.display_options.style.options.feature_properties missing schema

╵ /app/web/core/lib/Drupal/Core/Config/Development/ConfigSchemaChecker.php:98
╵ /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php:111
╵ /app/web/core/lib/Drupal/Core/Config/Config.php:229
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:278
╵ /app/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php:486
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php:257
╵ /app/web/core/lib/Drupal/Core/Entity/EntityBase.php:354
╵ /app/web/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:609
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_location/localgov_directories_location.install:47
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleHandler.php:400
╵ /app/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:364
╵ /app/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
╵ /app/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:475
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:561
╵ /app/web/core/tests/Drupal/Tests/BrowserTestBase.php:369
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

View Upgrade For Proximity Search (Drupal\Tests\localgov_directories_venue\Kernel\ViewUpgradeForProximitySearch)
✘ View upgrade

├ Exception: Exception when installing config for module localgov_directories_venue, message was: Schema errors for views.view.localgov_directory_channel with the following errors: views.view.localgov_directory_channel:display.embed_map.display_options.style.options.leaflet_popup.view_mode missing schema, views.view.localgov_directory_channel:display.embed_map.display_options.style.options.feature_properties missing schema

╵ /app/web/core/tests/Drupal/KernelTests/KernelTestBase.php:739
╵ /app/web/modules/contrib/localgov_directories/modules/localgov_directories_venue/tests/src/Kernel/ViewUpgradeForProximitySearchTest.php:86
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

Entity Reference Facets Widget (Drupal\Tests\localgov_directories\FunctionalJavascript\EntityReferenceFacetsWidget)
✘ Directory channel widget

├ SyntaxError: Unexpected token '.'
├ SyntaxError: Unexpected token '.'
├ SyntaxError: Unexpected token '.'

╵ /app/web/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php:138
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

✘ Facet required

├ SyntaxError: Unexpected token '.'
├ SyntaxError: Unexpected token '.'
├ SyntaxError: Unexpected token '.'

╵ /app/web/core/tests/Drupal/FunctionalJavascriptTests/WebDriverTestBase.php:138
╵ /app/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

ERRORS!
Tests: 31, Assertions: 492, Errors: 5, Failures: 2.

@finnlewis
Copy link
Member

Just mentioned this at Merge Tuesday. @andybroomfield is using this at BHCC and we are using this at Greenwich. So at least 2 councils are using this successfully.

Let's get it merged!

@finnlewis finnlewis self-assigned this Aug 20, 2024
@@ -24,6 +26,15 @@ function localgov_directories_location_install($is_syncing) {
return;
}

$index = SearchIndex::load(Directory::DEFAULT_INDEX);
$location_field = new SearchIndexField($index, Directory::LOCATION_FIELD_WKT);
Copy link
Contributor

@Adnan-cds Adnan-cds Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Ekes,
I am trying to understand the purpose behind this new localgov_location_wkt Search index field. Is it there to avoid the unwanted left join issue that Andy has pointed out?
Okay, don't worry. I can see it is of string type. Which suggests that it is for displaying the map popups only.

@finnlewis
Copy link
Member

@Adnan-cds want to do a little more testing before we merge this.

The test view was timing out hitting 128M of PHP memory, 256M was OK.

table: search_api_entity_geo_entity
field: location
relationship: localgov_location
search_api_rendered_item:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any use of this Search: Rendered item field anywhere in this View's display. If we drop this field, the embed_map display loads about a thousand map pins without any memory exhaustion issues in our site. So I would request that this search_api_rendered_item field be dropped.

I am still running into memory exhaustion issues around 1500 map pins after dropping the search_api_rendered_item field. But I don't yet see any easy way out of that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekes fancy adding this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm almost tempted to go the other way. If we're not including a freetext search based on rendered item in the default view maybe we should be?

@Adnan-cds
Copy link
Contributor

Hello, Ekes, Finn,
I think I am finished reviewing this. Ekes hinted earlier that using the database as the search backend will lead to entity loads which can be a bottleneck when large number of entities are involved. Initially I thought the changes from this pull request are avoiding that scenario. But now I can see that using the Content Entity Search API data source indeed leads to entity loads irrespective of the search backend. The Solr document data source seems to do a better job as Ekes pointed out. I am assuming that's the data source you are using in your current project.

I have suggested a small config change above which cuts memory usage somewhat. I don't have anything more to propose. Thanks.

@finnlewis
Copy link
Member

Note: @millnut suggested we add to documentation to recommend using Apache Solr for any directories with more than 500 / 1000 pins.

@ekes
Copy link
Member Author

ekes commented Sep 11, 2024

\o/ schema errors fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants