Search by EGF PIN prefix

This commit is contained in:
Claude Brisson
2024-04-14 10:31:05 +02:00
parent 02c6730336
commit 52d73ac9c2
2 changed files with 60 additions and 42 deletions

View File

@@ -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,6 +71,13 @@ class PlayerIndex {
}
fun match(needle: String, origins: Int, country: String?): List<Int> {
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("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(?<!\\b)-)"), "")
.split(Regex("[ -_']+"))
@@ -88,16 +98,23 @@ class PlayerIndex {
.add(filter, BooleanClause.Occur.FILTER)
.build()
}
2 -> {
if (activeMask.countOneBits() > 2) {
val filter =
TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf((origins xor activeMask) and activeMask)))
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 {
@@ -114,3 +131,4 @@ class PlayerIndex {
return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList()
}
}
}

View File

@@ -302,7 +302,7 @@
#[[
<script id="result" type="text/template">
{{for #data}}
<div class="result-line" data-index="{{:#getIndex()}}" data-name="{{:name}}">[{{:origin}}] {{:country}} - {{:name}} {{:firstname}} {{:rank}} ({{:club}}) {{if country === 'FR' && license !== 'L'}}<span class="darkred">non licencié</span>{{/if}}</div>
<div class="result-line" data-index="{{:#getIndex()}}" data-name="{{:name}}">[{{:origin}}{{if origin === 'EGF'}} {{:egf}}{{/if}}] {{:country}} - {{:name}} {{:firstname}} {{:rank}} ({{:club}}) {{if country === 'FR' && license !== 'L'}}<span class="darkred">non licencié</span>{{/if}}</div>
{{/for}}
</script>
<script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script>