From 232fe380034dd29353a640fd95500d0857e78705 Mon Sep 17 00:00:00 2001 From: odile Date: Fri, 9 Jan 2026 12:57:06 -0500 Subject: [PATCH 1/5] use position field in taxon_names to determine level of boost --- lib/controllers/v1/search_controller.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/controllers/v1/search_controller.js b/lib/controllers/v1/search_controller.js index a6b636e9..5e80f12c 100644 --- a/lib/controllers/v1/search_controller.js +++ b/lib/controllers/v1/search_controller.js @@ -76,13 +76,14 @@ SearchController.search = async req => { boost: 1 } }, - // match the nested name_autocomplete field in the taxa index + // match the nested name_autocomplete field in the taxa index, factoring + // in name position { - constant_score: { - filter: { - nested: { - path: "names", - ignore_unmapped: true, + nested: { + path: "names", + ignore_unmapped: true, + query: { + function_score: { query: { match: { "names.name_autocomplete": { @@ -92,10 +93,14 @@ SearchController.search = async req => { operator: "and" } } - } + }, + script_score: { + script: "2 / (1 + doc['names.position'].value)" + }, + boost_mode: "replace" } }, - boost: 2 + score_mode: "max" } }, // boost exact matches in the taxa index From aa044350c5d060da9ab9a85c1e996ae5c190e7e9 Mon Sep 17 00:00:00 2001 From: odile Date: Fri, 9 Jan 2026 15:24:03 -0500 Subject: [PATCH 2/5] increase rate decay of score as position drops --- lib/controllers/v1/search_controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/v1/search_controller.js b/lib/controllers/v1/search_controller.js index 5e80f12c..b262e5b6 100644 --- a/lib/controllers/v1/search_controller.js +++ b/lib/controllers/v1/search_controller.js @@ -95,7 +95,7 @@ SearchController.search = async req => { } }, script_score: { - script: "2 / (1 + doc['names.position'].value)" + script: "2 / (1 + (1.5 * doc['names.position'].value))" }, boost_mode: "replace" } From f2f855152db27bfc0ba9d9f0448841503f0ddd13 Mon Sep 17 00:00:00 2001 From: odile Date: Fri, 9 Jan 2026 17:02:14 -0500 Subject: [PATCH 3/5] use is_valid instead of position --- lib/controllers/v1/search_controller.js | 79 ++++++++++++++++++------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/lib/controllers/v1/search_controller.js b/lib/controllers/v1/search_controller.js index b262e5b6..328968e7 100644 --- a/lib/controllers/v1/search_controller.js +++ b/lib/controllers/v1/search_controller.js @@ -76,31 +76,70 @@ SearchController.search = async req => { boost: 1 } }, - // match the nested name_autocomplete field in the taxa index, factoring - // in name position + // match the nested name_autocomplete field in the taxa index, boosting valid names { - nested: { - path: "names", - ignore_unmapped: true, - query: { - function_score: { + constant_score: { + filter: { + nested: { + path: "names", + ignore_unmapped: true, query: { - match: { - "names.name_autocomplete": { - fuzziness: "AUTO", - prefix_length: 5, - query: q, - operator: "and" - } + bool: { + must: [ + { + match: { + "names.name_autocomplete": { + fuzziness: "AUTO", + prefix_length: 5, + query: q, + operator: "and" + } + } + }, + { + term: { + "names.is_valid": true + } + } + ] + } + } + } + }, + boost: 2 + } + }, + // match the nested name_autocomplete field in the taxa index for invalid names + { + constant_score: { + filter: { + nested: { + path: "names", + ignore_unmapped: true, + query: { + bool: { + must: [ + { + match: { + "names.name_autocomplete": { + fuzziness: "AUTO", + prefix_length: 5, + query: q, + operator: "and" + } + } + }, + { + term: { + "names.is_valid": false + } + } + ] } - }, - script_score: { - script: "2 / (1 + (1.5 * doc['names.position'].value))" - }, - boost_mode: "replace" + } } }, - score_mode: "max" + boost: 0.5 } }, // boost exact matches in the taxa index From b316a02c85cdd69fdaf81cb7f45c8e23f36d0ea2 Mon Sep 17 00:00:00 2001 From: odile Date: Mon, 12 Jan 2026 15:11:29 -0500 Subject: [PATCH 4/5] no longer penalizes if is_valid is null --- lib/controllers/v1/search_controller.js | 82 +++++++++++++++++-------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/lib/controllers/v1/search_controller.js b/lib/controllers/v1/search_controller.js index 328968e7..40c6162c 100644 --- a/lib/controllers/v1/search_controller.js +++ b/lib/controllers/v1/search_controller.js @@ -76,37 +76,69 @@ SearchController.search = async req => { boost: 1 } }, - // match the nested name_autocomplete field in the taxa index, boosting valid names + // match the nested name_autocomplete field in the taxa index { - constant_score: { - filter: { - nested: { - path: "names", - ignore_unmapped: true, - query: { - bool: { - must: [ - { - match: { - "names.name_autocomplete": { - fuzziness: "AUTO", - prefix_length: 5, - query: q, - operator: "and" + bool: { + should: [ + { + nested: { + path: "names", + ignore_unmapped: true, + query: { + bool: { + must: [ + { + match: { + "names.name_autocomplete": { + fuzziness: "AUTO", + prefix_length: 5, + query: q, + operator: "and" + } } } - }, - { - term: { - "names.is_valid": true + ], + must_not: [ + { + term: { + "names.is_valid": false + } } - } - ] - } + ] + } + }, + boost: 2 + } + }, + { + nested: { + path: "names", + ignore_unmapped: true, + query: { + bool: { + must: [ + { + match: { + "names.name_autocomplete": { + fuzziness: "AUTO", + prefix_length: 5, + query: q, + operator: "and" + } + } + }, + { + term: { + "names.is_valid": false + } + } + ] + } + }, + boost: 0.5 } } - }, - boost: 2 + ] } }, // match the nested name_autocomplete field in the taxa index for invalid names From 96166fc4108f68cd4d25642000a7ca69557cb45b Mon Sep 17 00:00:00 2001 From: odile Date: Mon, 12 Jan 2026 16:05:27 -0500 Subject: [PATCH 5/5] returns score on fuzzy match if is valid is null --- lib/controllers/v1/search_controller.js | 112 +++++------------------- 1 file changed, 21 insertions(+), 91 deletions(-) diff --git a/lib/controllers/v1/search_controller.js b/lib/controllers/v1/search_controller.js index 40c6162c..7cd22fcc 100644 --- a/lib/controllers/v1/search_controller.js +++ b/lib/controllers/v1/search_controller.js @@ -78,100 +78,30 @@ SearchController.search = async req => { }, // match the nested name_autocomplete field in the taxa index { - bool: { - should: [ - { - nested: { - path: "names", - ignore_unmapped: true, - query: { - bool: { - must: [ - { - match: { - "names.name_autocomplete": { - fuzziness: "AUTO", - prefix_length: 5, - query: q, - operator: "and" - } - } - } - ], - must_not: [ - { - term: { - "names.is_valid": false - } - } - ] - } - }, - boost: 2 - } - }, - { - nested: { - path: "names", - ignore_unmapped: true, - query: { - bool: { - must: [ - { - match: { - "names.name_autocomplete": { - fuzziness: "AUTO", - prefix_length: 5, - query: q, - operator: "and" - } - } - }, - { - term: { - "names.is_valid": false - } - } - ] - } - }, - boost: 0.5 - } - } - ] - } - }, - // match the nested name_autocomplete field in the taxa index for invalid names - { - constant_score: { - filter: { - nested: { - path: "names", - ignore_unmapped: true, + nested: { + path: "names", + ignore_unmapped: true, + query: { + function_score: { query: { - bool: { - must: [ - { - match: { - "names.name_autocomplete": { - fuzziness: "AUTO", - prefix_length: 5, - query: q, - operator: "and" - } - } - }, - { - term: { - "names.is_valid": false - } - } - ] + match: { + "names.name_autocomplete": { + fuzziness: "AUTO", + prefix_length: 5, + query: q, + operator: "and" + } } - } + }, + script_score: { + script: { + source: "doc['names.is_valid'].size() == 0 || doc['names.is_valid'].value == false ? 0.5 : 2.0" + } + }, + boost_mode: "replace", + score_mode: "max" } - }, - boost: 0.5 + } } }, // boost exact matches in the taxa index