[Bug 42835] New: ElasticSearch should have an items index
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Bug ID: 42835 Summary: ElasticSearch should have an items index Initiative type: --- Sponsorship --- status: Product: Koha Version: Main Hardware: All OS: All Status: NEW Severity: normal Priority: P5 - low Component: Searching - Elasticsearch Assignee: koha-bugs@lists.koha-community.org Reporter: pedro.amorim@openfifth.co.uk QA Contact: testopia@bugs.koha-community.org Target Milestone: --- -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |Needs Signoff -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #1 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200312 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200312&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #2 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200313 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200313&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #3 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200314 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200314&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #4 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200315 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200315&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #5 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200316 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200316&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #6 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200317 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200317&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 David Nind <david@davidnind.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |david@davidnind.com Assignee|koha-bugs@lists.koha-commun |pedro.amorim@openfifth.co.u |ity.org |k --- Comment #7 from David Nind <david@davidnind.com> --- Added assignee 8-) -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |pedro.amorim@openfifth.co.u | |k Status|Needs Signoff |Patch doesn't apply -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Patch doesn't apply |Needs Signoff -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #200312|0 |1 is obsolete| | Attachment #200313|0 |1 is obsolete| | Attachment #200314|0 |1 is obsolete| | Attachment #200315|0 |1 is obsolete| | Attachment #200316|0 |1 is obsolete| | Attachment #200317|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #8 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200605 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200605&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #9 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200606 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200606&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #10 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200607 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200607&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #11 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200608 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200608&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #12 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200609 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200609&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #13 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 200610 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=200610&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrew@bywatersolutions.com | |, | |martin.renvoize@openfifth.c | |o.uk, | |nick@bywatersolutions.com -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |42643 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42643 [Bug 42643] [OMNIBUS] Assorted performance and stability work -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |42958 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42958 [Bug 42958] Expand Elasticsearch/Opensearch usage across Koha beyond bibliographic search -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Strategic theme|--- |Performance Target Milestone|--- |26.11 Initiative type|--- |Epic -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Initiative type|Epic |Feature -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks|42643 | Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42643 [Bug 42643] [OMNIBUS] Assorted performance and stability work -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 David Nind <david@davidnind.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Needs Signoff |Signed Off -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 David Nind <david@davidnind.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #200605|0 |1 is obsolete| | Attachment #200606|0 |1 is obsolete| | Attachment #200607|0 |1 is obsolete| | Attachment #200608|0 |1 is obsolete| | Attachment #200609|0 |1 is obsolete| | Attachment #200610|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #14 from David Nind <david@davidnind.com> --- Created attachment 202138 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202138&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #15 from David Nind <david@davidnind.com> --- Created attachment 202139 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202139&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #16 from David Nind <david@davidnind.com> --- Created attachment 202140 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202140&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #17 from David Nind <david@davidnind.com> --- Created attachment 202141 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202141&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #18 from David Nind <david@davidnind.com> --- Created attachment 202142 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202142&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #19 from David Nind <david@davidnind.com> --- Created attachment 202143 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202143&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 David Nind <david@davidnind.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |release-notes-needed --- Comment #20 from David Nind <david@davidnind.com> --- Testing notes (using KTD): 1. Tested using Elasticsearch 9: ktd --search-engine es9 up -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Signed Off |Patch doesn't apply -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Patch doesn't apply |Signed Off -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #202138|0 |1 is obsolete| | Attachment #202139|0 |1 is obsolete| | Attachment #202140|0 |1 is obsolete| | Attachment #202141|0 |1 is obsolete| | Attachment #202142|0 |1 is obsolete| | Attachment #202143|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #21 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202229 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202229&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #22 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202230 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202230&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #23 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202231 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202231&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #24 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202232 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202232&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #25 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202233 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202233&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #26 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202234 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202234&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43151 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43151 [Bug 43151] ES should apply search filters on each item discretely -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #202229|0 |1 is obsolete| | Attachment #202230|0 |1 is obsolete| | Attachment #202231|0 |1 is obsolete| | Attachment #202232|0 |1 is obsolete| | Attachment #202233|0 |1 is obsolete| | Attachment #202234|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #27 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202480 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202480&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #28 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202481 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202481&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #29 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202482 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202482&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #30 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202483 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202483&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #31 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202484 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202484&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #32 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202485 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202485&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #33 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202486 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202486&action=edit Bug 42835: (follow-up) Cache items index queries for availability and facets _get_available_biblionumbers() and _get_item_facets() hit the items index on every search, unscoped and uncached. Fine on a small catalog, brutal at real scale - hundreds of round-trips per "available" search. Cache both for 15s. Single key for availability (same result for everyone); MD5-of-biblionumbers key for facets (result is per-search). Test plan: 1) prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t 2) Run demo_cache_fix.pl - second call to each function should be near-instant vs the first Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #34 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 202487 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=202487&action=edit Bug 42835: [DO NOT PUSH]: demo script for items index caching fix Standalone script demonstrating the caching fix in the previous commit. Wraps the real ES client to count calls, then calls _get_available_biblionumbers() and _get_item_facets() twice each against a live KTD Elasticsearch instance - first call should hit ES, second should be near-instant from cache. Run: perl demo_cache_fix.pl This commit is for local testing only and must not be pushed upstream. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #35 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Squashed in a fix restoring the Try::Tiny import to Koha/Item.pm, removed by bug 42391. Added caching to items index queries for availability and facets. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Sponsorship status|--- |Sponsored Comma delimited| |Cuyahoga County Public list of Sponsors| |Library -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Lisette Scheer <lisette@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- QA Contact|testopia@bugs.koha-communit |Laura.escamilla@bywatersolu |y.org |tions.com CC| |lisette@bywatersolutions.co | |m -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |35052 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=35052 [Bug 35052] OpacHiddenItemsHidesRecord system preference should be considered on index time instead -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Signed Off |Failed QA --- Comment #36 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Some things coming out of a QA review: 1. misc/search_tools/rebuild_elasticsearch.pl:269-271, _do_reindex_items — the new --items path isn't slice-aware. Biblios/authorities reindexing forks --processes N workers and gives each a slice => {index, count} so the table is partitioned across them. _do_reindex_items ignores %iterator_options entirely and does Koha::Items->search({}) unconditionally — every forked worker (not just the parent) reindexes the entire items table independently. Still correct (idempotent by itemnumber), but on a large catalog --items --processes 4 does 4x the ES writes and DB scans instead of dividing the work, defeating the point of --processes. 2. Koha/Item.pm:73-78 (%ITEM_CIRC_FIELDS) — holdingbranch is deliberately in the "skip biblio reindex" set (per the commit message: "AddIssue always sets it alongside onloan"), so ordinary checkouts still qualify for the fast path. But that means a genuine branch transfer (also just a holdingbranch change) skips the biblio reindex too. The items-index facets stay correct (they're queried live), but the ES-stored MARC blob used to render search-result rows (branch/location shown per hit) goes stale until some unrelated reindex trigger fires. Net effect: after a transfer, the facet count and the actual result-row "held at" branch can disagree. 3. No test coverage for the actual N+1 fix — C4/Search.pm's new pre-scan/batched visibility check (searchResults() ~1740-1765, ~1895-1905) has no corresponding change in t/db_dependent/Search.t. Every other piece of this patchset (readiness gate, caching, items index CRUD) has solid test coverage confirmed by direct reading; this is the one production change that ships untested — worth a test with a mixed visible/hidden batch, an empty batch, and the fallback-to-per-item path. And, some possible nice to haves: 1. C4/Search.pm:1750/1752 vs 1774/1778 — the visibility pre-scan parses every page's MARC record with MARC::Record->new_from_usmarc/new_record_from_zebra, then the main loop parses the same record again. Cheap relative to the DB round-trips saved, but stashing the already-parsed record from the pre-scan and reusing it would remove the duplicate work entirely. 2. Koha/SearchEngine/Elasticsearch.pm — adds Readonly our $ITEMS_INDEX => 'items'; locally even though the file now also does use Koha::SearchEngine;, which defines the same constant. Matches the file's pre-existing (already duplicated) $BIBLIOS_INDEX/$AUTHORITIES_INDEX pattern, so not new, but a third duplicate constant is a good excuse to collapse to one source of truth. 3. POD is thin on Koha::Item::_update_es_index and Koha::SearchEngine::Elasticsearch::Indexer::_item_to_document (headers present, no real description). 4. Search.pm:search_compat now always adds a _biblionumbers terms aggregation (size => 9_000) plus a second ES round-trip to the items index for facets, on every biblios-index search once the items index is ready — even for callers that don't use the returned facets. Not a bug, but worth confirming it doesn't add measurable per-search latency on large result sets. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #37 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203718 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203718&action=edit Bug 42835: (QA follow-up) Make --items slice-aware for --processes _do_reindex_items() ignored %iterator_options and always reindexed the whole items table per forked process, instead of just its own slice. Test plan: 1) Run: perl misc/search_tools/rebuild_elasticsearch.pl --items --reset --processes 3 --verbose 2) Check the output: you should see 3 different "Processing slice" lines and 3 different item counts that add up to your total, not the same full count three times. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #38 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203719 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203719&action=edit Bug 42835: (QA follow-up) Don't skip biblio re-index on branch transfer A standalone holdingbranch change (transfer) was wrongly treated as safe to skip, same as a checkout. Now, when holdingbranch changes, the skip only applies if onloan or issues changed too. Test plan: 1) Run: prove t/db_dependent/Koha/Item.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #39 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203720 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203720&action=edit Bug 42835: (QA follow-up) Add test coverage for OPAC item visibility batching C4::Search::searchResults() gained a pre-scan that batches the OPAC item-visibility check into one DB call per page instead of one per item, but shipped with no corresponding test. Add coverage for a mixed visible/hidden batch, a batch with no items at all, and the per-item fallback path. The fallback is exercised by mocking MARC parsing to fail only during the pre-scan, forcing the old per-item lookup to run instead of the batched one. Test plan: 1) Run: prove t/db_dependent/Search.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #40 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203721 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203721&action=edit Bug 42835: (QA follow-up) Reuse pre-scanned MARC record in searchResults() The OPAC item-visibility pre-scan already parses every record on the page to collect itemnumbers, then the main loop parsed the same records again a few lines later. Stash the parsed record from the pre-scan and reuse it, instead of parsing twice. Test plan: 1) Run: prove t/db_dependent/Search.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #41 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203722 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203722&action=edit Bug 42835: (QA follow-up) Document Koha::Item::_update_es_index This file documents its other private subs (_add_statistic, _status, _set_found_trigger) with a usage synopsis and description; _update_es_index only had a bare header. Fill it in to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #42 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 203723 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=203723&action=edit Bug 42835: [DO NOT PUSH] demo script for facets round-trip latency Benchmarks search_compat()'s two added costs on ~9k synthetic biblios (matching the _biblionumbers aggregation's own size cap): the extra terms aggregation on the biblios query, and the second round-trip to _get_item_facets. Cold-cache worst case adds ~25-55ms on top of a ~20-25ms baseline query, but the item-facets round-trip is cached, so repeated searches against the same result set pay far less. The script's verdict line checks the total round-trip against a configurable "still feels instant" budget ($ACCEPTABLE_TOTAL_MS, currently 100ms) rather than asserting a fixed conclusion -- every run so far has landed well under that budget, so no follow-up fix is warranted here. This commit is for local testing only and must not be pushed upstream. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Failed QA |Signed Off -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks|35052 | Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=35052 [Bug 35052] OpacHiddenItemsHidesRecord system preference should be considered on index time instead -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #43 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Nice work Pedro.. apologies I didn't come back to this sooner.. I somehow missed the follow-ups had been posted :) -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #44 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- The items-index availability/facets caches (_get_available_biblionumbers(), _get_item_facets() in Koha/SearchEngine/Elasticsearch/Search.pm) now uses a 15s TTL to avoid re-scanning the items index on every "available" search. I looked at adding immediate cache invalidation on every circulation event (checkout/checkin/transfer/edit), but decided against it: it would require a global invalidation trigger that fires on any item change anywhere in the instance, which significantly reduces the caching benefit during busy circulation periods — exactly when the caching matters most for protecting Elasticsearch from load. I felt a 15s worst-case staleness window on availability/facets is close enough to real-time that it shouldn't be perceptible to end users in normal use. Documenting this as a known, accepted trade-off rather than fixing it: for up to 15 seconds after a checkout/checkin, the "available" search filter and item-count facets may not yet reflect the very latest circulation activity for an affected biblio. Everything else (item state itself, the items index, non-cached lookups) is updated synchronously. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #202480|0 |1 is obsolete| | Attachment #202481|0 |1 is obsolete| | Attachment #202482|0 |1 is obsolete| | Attachment #202483|0 |1 is obsolete| | Attachment #202484|0 |1 is obsolete| | Attachment #202485|0 |1 is obsolete| | Attachment #202486|0 |1 is obsolete| | Attachment #202487|0 |1 is obsolete| | Attachment #203718|0 |1 is obsolete| | Attachment #203719|0 |1 is obsolete| | Attachment #203720|0 |1 is obsolete| | Attachment #203721|0 |1 is obsolete| | Attachment #203722|0 |1 is obsolete| | Attachment #203723|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #45 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205410 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205410&action=edit Bug 42835: Elasticsearch: Add items index Adds a dedicated 'items' Elasticsearch index where each item is its own flat document keyed by itemnumber, built from Koha::Item data rather than MARC. Adds index_items() and delete_items() to Indexer.pm. Hooks into Item::store() and Item::delete() via _update_es_index() to keep the index in sync on every item change; a skip_items_index flag allows bulk operations to bypass it. Items in their own index can be updated on circulation without re-parsing MARC, keeping availability and facet counts accurate in real time. Adds a noop mock for index_items in the Elasticsearch.t test fixture to prevent store() calls inside marc_records_to_documents tests from trying to index items into ES. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #46 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205411 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205411&action=edit Bug 42835: Koha::Item: Skip biblio re-index for circulation-only field changes When only fields in %ITEM_CIRC_FIELDS are modified (onloan, issues, renewals, holdingbranch, datelastborrowed, datelastseen, localuse, reserves, timestamp), skip the biblio MARC re-index — the items index is authoritative for this data. notforloan, damaged, itemlost and withdrawn are excluded from the skip set: they affect the available field in the biblios index and must trigger a re-index to keep availability filtering correct. The skip is further gated on _items_index_ready(): the biblio re-index is only skipped when the items index is sufficiently populated (>=95% of DB items indexed). This prevents stale availability data on fresh installs where the items index may contain only a handful of documents. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #47 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205412 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205412&action=edit Bug 42835: rebuild_elasticsearch.pl: Add --items flag Adds -i|--items to rebuild the items index from the database (not from MARC). Items are not included in the default "index everything" behaviour and must be requested explicitly. Also adds -in|--itemnumber to reindex one or more specific items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #48 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205413 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205413&action=edit Bug 42835: Elasticsearch: Route availability and facets through items index Queries the items index for availability filtering and item-level facets (itype, location, ccode, homebranch, holdingbranch). Uses cardinality sub-aggregations for per-biblio facet counts rather than per-item counts. Adds biblionumber as an explicit integer field in the biblios index mapping and stamps it on biblio documents so item facet queries can be scoped to the current search result set via a _biblionumbers aggregation. Fixes a bug where _apply_available_filter assumed available:true was always at must[0]; now scans all must elements. Fixes a bug where biblio_count{value} was tested for hashref truthiness rather than key existence, always preferring it over doc_count. Fixes the biblios index available field to correctly treat notforloan, damaged, and withdrawn items as unavailable — previously only onloan and itemlost were checked. Covers both item-level notforloan and items whose item type has notforloan set. Updates existing tests in Elasticsearch.t that were asserting the previous wrong behaviour. Items index routing is unconditional here; the readiness gate that prevents empty-index regressions on upgrade is added in the next commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #49 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205414 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205414&action=edit Bug 42835: OPAC performance: Batch item visibility check to reduce N+1 DB queries Before the main result loop, pre-scan all MARC records for the current page to collect every itemnumber in one pass. Run a single batched filter_by_visible_in_opac call and store the result in a hash. The inner item loop then does a plain hash lookup instead of one Koha::Items DB query per item, reducing N queries to 1 per page load. Falls back to the per-item path if no itemnumbers are found in the pre-scan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #50 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205415 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205415&action=edit Bug 42835: Elasticsearch: Gate items index features behind readiness check Adds _items_index_ready() which checks whether the items index is fully populated before enabling availability filtering and facet aggregation. The index is considered ready only when it contains at least 95% of the items in the database — this prevents the gate opening after a single circulation event has indexed one item before rebuild_elasticsearch.pl --items has been run. The result is cached: 5 minutes when ready, 60 seconds when not, so a freshly populated index is detected quickly without a restart. TEST PLAN (Do not apply patches yet) 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you get 40 results. 9 of these bibs have all their items unavailable and should NOT be showing. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. 9) Let's pick a 2nd bib from that same search ('music' + only available): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 10) Edit that single item, put it 'Not for loan' 11) Refresh the search. Notice the bib is always showing, even though all its items are unavailable (This is incorrect): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available APPLY PATCHES 1) Set up KTD with Elasticsearch 8: ktd --search-engine es8 up 2) Do a search for 'music', you should get 42 results: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music 3) Click the 'Limit to records with available items' facet link. Notice you now get 31 results. The previous 9 with all their items unavailable do not show anymore. 4) Find a biblio with a single item (the top result of the search): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=437 5) Check-out that item (39999000019186) to a patron 6) Repeat the same search with 'Limit to records with available items'. Notice the biblio above is no longer showing (this is still correct). 7) Check the background jobs: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 8) Confirm at least 1 'Update Elasticsearch index' entry exists. This is because a full bib reindex is triggered for anytime a check-out happens. This is still the case because a full reindex (to create the items index) has not occurred yet. Let's do that 9) Run: $ perl misc/search_tools/rebuild_elasticsearch.pl -i -r -v 10) Do another check-out for a 2nd bib with a single item e.g. (39999000016710): http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=380 11) Check the background jobs again: http://localhost:8081/cgi-bin/koha/admin/background_jobs.pl 12) Notice a new full bib record reindex job was not triggered, because this was updated directly on the items index synchronously. Confirm that bib record no longer shows on the 'only available' search: http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available 13) Pick a third bib from the same search http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=374 14) Edit the single item and put it 'not for loan'. 15) Refresh the search. Notice the bib is not showing anymore, because all its items are unavailable (This is now correct): http://localhost:8081/cgi-bin/koha/catalogue/search.pl?idx=&q=music&weight_search=1&sort_by=relevance&limit=available Benefits: 1. notforloan/damaged/withdrawn availability fix 2. Skip biblio re-index on checkout — performance improvement, visible under load 3. Availability filtering via items index — real-time post-checkout 4. Safe on upgrade — falls back to the biblios index until a rebuild with --items is run, no hard requirement to rebuild before the system works correctly. Run tests: prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Indexer.t prove t/db_dependent/Koha/SearchEngine/Elasticsearch.t prove t/db_dependent/Koha/Item.t prove t/db_dependent/Search.t prove t/db_dependent/Koha/SearchEngine/Search.t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #51 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205416 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205416&action=edit Bug 42835: (follow-up) Cache items index queries for availability and facets _get_available_biblionumbers() and _get_item_facets() hit the items index on every search, unscoped and uncached. Fine on a small catalog, brutal at real scale - hundreds of round-trips per "available" search. Cache both for 15s. Single key for availability (same result for everyone); MD5-of-biblionumbers key for facets (result is per-search). Test plan: 1) prove t/db_dependent/Koha/SearchEngine/Elasticsearch/Search.t 2) Run demo_cache_fix.pl - second call to each function should be near-instant vs the first Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #52 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205417 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205417&action=edit Bug 42835: [DO NOT PUSH]: demo script for items index caching fix Standalone script demonstrating the caching fix in the previous commit. Wraps the real ES client to count calls, then calls _get_available_biblionumbers() and _get_item_facets() twice each against a live KTD Elasticsearch instance - first call should hit ES, second should be near-instant from cache. Run: perl demo_cache_fix.pl This commit is for local testing only and must not be pushed upstream. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #53 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205418 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205418&action=edit Bug 42835: (QA follow-up) Make --items slice-aware for --processes _do_reindex_items() ignored %iterator_options and always reindexed the whole items table per forked process, instead of just its own slice. Test plan: 1) Run: perl misc/search_tools/rebuild_elasticsearch.pl --items --reset --processes 3 --verbose 2) Check the output: you should see 3 different "Processing slice" lines and 3 different item counts that add up to your total, not the same full count three times. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #54 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205419 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205419&action=edit Bug 42835: (QA follow-up) Don't skip biblio re-index on branch transfer A standalone holdingbranch change (transfer) was wrongly treated as safe to skip, same as a checkout. Now, when holdingbranch changes, the skip only applies if onloan or issues changed too. Test plan: 1) Run: prove t/db_dependent/Koha/Item.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #55 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205420 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205420&action=edit Bug 42835: (QA follow-up) Add test coverage for OPAC item visibility batching C4::Search::searchResults() gained a pre-scan that batches the OPAC item-visibility check into one DB call per page instead of one per item, but shipped with no corresponding test. Add coverage for a mixed visible/hidden batch, a batch with no items at all, and the per-item fallback path. The fallback is exercised by mocking MARC parsing to fail only during the pre-scan, forcing the old per-item lookup to run instead of the batched one. Test plan: 1) Run: prove t/db_dependent/Search.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #56 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205421 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205421&action=edit Bug 42835: (QA follow-up) Reuse pre-scanned MARC record in searchResults() The OPAC item-visibility pre-scan already parses every record on the page to collect itemnumbers, then the main loop parsed the same records again a few lines later. Stash the parsed record from the pre-scan and reuse it, instead of parsing twice. Test plan: 1) Run: prove t/db_dependent/Search.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #57 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205422 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205422&action=edit Bug 42835: (QA follow-up) Document Koha::Item::_update_es_index This file documents its other private subs (_add_statistic, _status, _set_found_trigger) with a usage synopsis and description; _update_es_index only had a bare header. Fill it in to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #58 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205423 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205423&action=edit Bug 42835: [DO NOT PUSH] demo script for facets round-trip latency Benchmarks search_compat()'s two added costs on ~9k synthetic biblios (matching the _biblionumbers aggregation's own size cap): the extra terms aggregation on the biblios query, and the second round-trip to _get_item_facets. Cold-cache worst case adds ~25-55ms on top of a ~20-25ms baseline query, but the item-facets round-trip is cached, so repeated searches against the same result set pay far less. The script's verdict line checks the total round-trip against a configurable "still feels instant" budget ($ACCEPTABLE_TOTAL_MS, currently 100ms) rather than asserting a fixed conclusion -- every run so far has landed well under that budget, so no follow-up fix is warranted here. This commit is for local testing only and must not be pushed upstream. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #59 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205424 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205424&action=edit Bug 42835: (QA follow-up) Stop items-index ES calls and SearchEngine pref leaking out of Item.t The 'skip biblio re-index for circ-only field changes' subtest mocks SearchEngine to 'Elasticsearch' via t::lib::Mocks::mock_preference, which overrides a process-global hash with no automatic restore. It was never reset back, so every later store() call in the file - including the many inside the 'Recalls tests' subtest - went on to run with SearchEngine still set to 'Elasticsearch'. Koha::Item::store() calls _update_es_index() unconditionally on that preference, which builds a real Koha::SearchEngine::Elasticsearch::Indexer and calls index_items()/delete_items() on it. Only index_records() was mocked on that class, so those calls were free to reach a real (or unreachable) Elasticsearch cluster from a plain Perl unit test - in the latter case, the resulting warn() would fail the file's Test::NoWarnings check. Mock index_items()/delete_items() as no-ops alongside index_records(), and restore SearchEngine to 'Zebra' at the end of the subtest, matching the pattern already used elsewhere (e.g. t/db_dependent/Koha/Authorities.t). Test plan: 1) Run: prove t/db_dependent/Koha/Item.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #60 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 205425 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=205425&action=edit Bug 42835: (QA follow-up) Only treat a genuine holdingbranch value change as a transfer The previous fix for skipping the biblio re-index on branch transfers used exists $updated_columns{onloan} / {issues} as a proxy for "this is a checkout, not a transfer". That misses the case where a checkout also moves the item to a different branch than it currently has: onloan being dirty made is_branch_transfer false, so the branch-facet-relevant change was silently skipped along with the safe circ-only fields. Compare the actual holdingbranch value against the pre-store item instead of looking at which other columns happen to be dirty. A holdingbranch value that hasn't actually changed (AddIssue re-asserting the current branch alongside onloan) is still skippable; any real branch change now always forces a re-index, regardless of what else changed in the same store() call. Test plan: 1) Run: prove t/db_dependent/Koha/Item.t Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43017 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43017 [Bug 43017] [OMNIBUS] Interface optimization -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Lisette Scheer <lisette@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- QA Contact|Laura.escamilla@bywatersolu |aleisha@catalyst.net.nz |tions.com | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Lisette Scheer <lisette@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- QA Contact|aleisha@catalyst.net.nz |nick@bywatersolutions.com -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Luis Bataller <luis.bataller@xercode.es> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |luis.bataller@xercode.es -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 David Cook <dcook@prosentient.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dcook@prosentient.com.au -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #61 from David Cook <dcook@prosentient.com.au> --- I'll have to come take a look at this later. Sounds interesting though... -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |melia@bywatersolutions.com --- Comment #62 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- *** Bug 8589 has been marked as a duplicate of this bug. *** -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #63 from Luis Bataller <luis.bataller@xercode.es> --- Hi, Thanks for picking this up — indexing item data in Elasticsearch is something Koha has needed for a long time. We went through this same design question some months ago and evaluated both options: a separate item index, and items as `nested` objects inside the biblio document. We ended up choosing `nested`. We picked up the existing bug 8589 to offer that work to the community, but we never attached the patches there — we offered them and then let it drop, mostly on our side. The implementation is now in pre-production on an installation with roughly 1.5 million biblio records and 8 million items. A search filtered only by item attributes works fine with a separate index — that matches what bug 42835 currently implements, as far as I can tell. The difficulty we hit was with queries mixing item-level and biblio-level criteria, which is the common shape in both the OPAC and the staff interface. What follows is a summary of the analysis we carried out against that catalogue. --- Our reference case was the most frequent one: **library = b, title like "..."**. In that catalogue the largest library holds around half a million items, which resolves to somewhere between 140,000 and 320,000 distinct biblionumbers depending on the local items-per-record ratio — 10-20% of the whole catalogue in a single intermediate set. Two problems followed: 1. **Intermediate set size.** Passing that many biblionumbers as a `terms` filter exceeds `index.max_terms_count` (65,536 by default). The workarounds we considered were splitting the query into chunks, which breaks global scoring and relevance ordering, or a `terms lookup`, which introduces a synchronous write plus a refresh in the middle of a read path. 2. **Relevance pagination.** The selective criterion is the title, so the biblio query has to run first, but then there is no way to know how many of its hits will survive the item filter. Filling a page of 20 results becomes an iterative loop with an unpredictable number of round-trips, or requires fetching the full candidate set and re-sorting in application code, losing BM25 scoring. --- So my main question is: have you already worked out how general searches combining item and biblio criteria would be resolved, particularly these two points? If you have a solution, I would genuinely like to understand it — the separate-index approach has real advantages we would benefit from, particularly a much lower cost for full reindexing when an item field is added. If it turns out to be an open problem, we would be glad to share what we have. The patches are not attached to bug 8589 yet, but we can post them there promptly if there is interest, whether as something to contribute or just as a reference for comparison. We are also happy to run comparative tests against our dataset if that would help validate either design. Thanks again for working on this. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 Fridolin Somers <fridolin.somers@biblibre.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |fridolin.somers@biblibre.co | |m --- Comment #64 from Fridolin Somers <fridolin.somers@biblibre.com> --- Ohhh looks great :D -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #65 from David Cook <dcook@prosentient.com.au> --- (In reply to Luis Bataller from comment #63)
Hi,
Thanks for picking this up — indexing item data in Elasticsearch is something Koha has needed for a long time.
We went through this same design question some months ago and evaluated both options: a separate item index, and items as `nested` objects inside the biblio document. We ended up choosing `nested`.
Great to meet you at the dev meeting last night, Luis. I agree with your analysis regarding having a separate item index vs having nested objects. To me, having a separate item index doesn't make sense, because it would be very inefficient at a large scale. That said, what have you observed with bib records with many (e.g. 200-1000 items) nested inside the JSON document in Elasticsearch? I am supportive of having nested items, because it allows for better searching, but I have only tried it with relatively small numbers of items embedded in the bib index. Actually with Elasticsearch I think that you can do includes/excludes with source filtering... so you could do a search against a large record but just retrieve the bib record when showing the search results... that could be very very useful. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #66 from David Cook <dcook@prosentient.com.au> --- @Luis, I mentioned it a bit in the chat last night, but the reason we haven't used nested items in the past in Elasticsearch is because we were trying to keep feature parity between Elasticsearch and Zebra, and Zebra has a flat index structure. However, as the use of Elasticsearch in Koha has matured/evolved, we have started doing more Elasticsearch-specific changes. And I think that your idea for nested items would be a really good Elasticsearch-specific change. I think we should be taking advantage of Elasticsearch's capabilities to improve Koha's search here. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=42835 --- Comment #67 from David Cook <dcook@prosentient.com.au> --- @Pedro @Martin I'm short on time, so I was hoping you could give me a concise summary of how your patches work having a separate item index? -- You are receiving this mail because: You are watching all bug changes.
participants (1)
-
bugzilla-daemon@bugs.koha-community.org