From 52d73ac9c293ab0ab29ea62c745a7ce561852eb1 Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Sun, 14 Apr 2024 10:31:05 +0200 Subject: [PATCH] Search by EGF PIN prefix --- .../jeudego/pairgoth/ratings/PlayerIndex.kt | 100 +++++++++++------- .../main/webapp/tour-registration.inc.html | 2 +- 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt index 1fe03de..5e1b6ba 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt @@ -1,7 +1,6 @@ package org.jeudego.pairgoth.ratings import com.republicate.kson.Json -import org.apache.lucene.analysis.LowerCaseFilter import org.apache.lucene.analysis.standard.StandardAnalyzer import org.apache.lucene.document.Document import org.apache.lucene.document.Field @@ -15,8 +14,8 @@ import org.apache.lucene.index.Term import org.apache.lucene.queryparser.complexPhrase.ComplexPhraseQueryParser import org.apache.lucene.search.BooleanClause import org.apache.lucene.search.BooleanQuery -import org.apache.lucene.search.FuzzyQuery import org.apache.lucene.search.IndexSearcher +import org.apache.lucene.search.PrefixQuery import org.apache.lucene.search.TermQuery import org.apache.lucene.store.ByteBuffersDirectory import org.apache.lucene.store.Directory @@ -32,6 +31,7 @@ class PlayerIndex { val FIRSTNAME = "firstname" val TEXT = "text" val COUNTRY = "country" + val PIN = "egf" val MAX_HITS = 20 val logger = LoggerFactory.getLogger("index") @@ -60,6 +60,9 @@ class PlayerIndex { doc.add(StringField(ORIGIN, player.field(ORIGIN).lowercase(Locale.ROOT), Field.Store.NO)) doc.add(StringField(COUNTRY, player.field(COUNTRY).lowercase(Locale.ROOT), Field.Store.NO)) doc.add(TextField(TEXT, "${player.field(NAME)} ${player.nullableField(FIRSTNAME)}", Field.Store.NO)) + player.getString(PIN)?.let { + doc.add(StringField(PIN, it, Field.Store.NO)) + } writer.addDocument(doc); ++count } @@ -68,49 +71,64 @@ class PlayerIndex { } fun match(needle: String, origins: Int, country: String?): List { - val terms = needle.lowercase(Locale.ROOT) - .replace(Regex("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(? return emptyList() - 1 -> { - val filter = TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf(origins))) - BooleanQuery.Builder() - .add(fuzzy, BooleanClause.Occur.SHOULD) - .add(filter, BooleanClause.Occur.FILTER) - .build() - } - 2 -> { - if (activeMask.countOneBits() > 2) { - val filter = - TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf((origins xor activeMask) and activeMask))) + if (needle.trim().matches(Regex("\\d+"))) { + // PIN search + val pin = needle.trim().toInt() + val query = PrefixQuery(Term(PIN, needle.trim())) + val docs = searcher.search(query, MAX_HITS) + return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList() + } else { + val terms = needle.lowercase(Locale.ROOT) + .replace(Regex("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(? return emptyList() + 1 -> { + val filter = TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf(origins))) BooleanQuery.Builder() .add(fuzzy, BooleanClause.Occur.SHOULD) - .add(filter, BooleanClause.Occur.MUST_NOT) + .add(filter, BooleanClause.Occur.FILTER) .build() - } else fuzzy - } - 3 -> fuzzy - else -> throw Error("wrong origins mask") - }.let { - if (country == null) it - else { - val countryFilter = TermQuery(Term(COUNTRY, country.lowercase(Locale.ROOT))) - BooleanQuery.Builder() - .add(it, BooleanClause.Occur.SHOULD) - .add(countryFilter, BooleanClause.Occur.FILTER) - .build() + } + + 2 -> { + if (activeMask.countOneBits() > 2) { + val filter = + TermQuery( + Term( + ORIGIN, + RatingsManager.Ratings.codeOf((origins xor activeMask) and activeMask) + ) + ) + BooleanQuery.Builder() + .add(fuzzy, BooleanClause.Occur.SHOULD) + .add(filter, BooleanClause.Occur.MUST_NOT) + .build() + } else fuzzy + } + + 3 -> fuzzy + else -> throw Error("wrong origins mask") + }.let { + if (country == null) it + else { + val countryFilter = TermQuery(Term(COUNTRY, country.lowercase(Locale.ROOT))) + BooleanQuery.Builder() + .add(it, BooleanClause.Occur.SHOULD) + .add(countryFilter, BooleanClause.Occur.FILTER) + .build() + } } + val docs = searcher.search(query, MAX_HITS) + return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList() } - val docs = searcher.search(query, MAX_HITS) - return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList() } } diff --git a/view-webapp/src/main/webapp/tour-registration.inc.html b/view-webapp/src/main/webapp/tour-registration.inc.html index c77a308..8d56998 100644 --- a/view-webapp/src/main/webapp/tour-registration.inc.html +++ b/view-webapp/src/main/webapp/tour-registration.inc.html @@ -302,7 +302,7 @@ #[[