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 package org.jeudego.pairgoth.ratings
import com.republicate.kson.Json import com.republicate.kson.Json
import org.apache.lucene.analysis.LowerCaseFilter
import org.apache.lucene.analysis.standard.StandardAnalyzer import org.apache.lucene.analysis.standard.StandardAnalyzer
import org.apache.lucene.document.Document import org.apache.lucene.document.Document
import org.apache.lucene.document.Field 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.queryparser.complexPhrase.ComplexPhraseQueryParser
import org.apache.lucene.search.BooleanClause import org.apache.lucene.search.BooleanClause
import org.apache.lucene.search.BooleanQuery import org.apache.lucene.search.BooleanQuery
import org.apache.lucene.search.FuzzyQuery
import org.apache.lucene.search.IndexSearcher import org.apache.lucene.search.IndexSearcher
import org.apache.lucene.search.PrefixQuery
import org.apache.lucene.search.TermQuery import org.apache.lucene.search.TermQuery
import org.apache.lucene.store.ByteBuffersDirectory import org.apache.lucene.store.ByteBuffersDirectory
import org.apache.lucene.store.Directory import org.apache.lucene.store.Directory
@@ -32,6 +31,7 @@ class PlayerIndex {
val FIRSTNAME = "firstname" val FIRSTNAME = "firstname"
val TEXT = "text" val TEXT = "text"
val COUNTRY = "country" val COUNTRY = "country"
val PIN = "egf"
val MAX_HITS = 20 val MAX_HITS = 20
val logger = LoggerFactory.getLogger("index") 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(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(StringField(COUNTRY, player.field(COUNTRY).lowercase(Locale.ROOT), Field.Store.NO))
doc.add(TextField(TEXT, "${player.field(NAME)} ${player.nullableField(FIRSTNAME)}", 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); writer.addDocument(doc);
++count ++count
} }
@@ -68,6 +71,13 @@ class PlayerIndex {
} }
fun match(needle: String, origins: Int, country: String?): List<Int> { 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) val terms = needle.lowercase(Locale.ROOT)
.replace(Regex("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(?<!\\b)-)"), "") .replace(Regex("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(?<!\\b)-)"), "")
.split(Regex("[ -_']+")) .split(Regex("[ -_']+"))
@@ -88,16 +98,23 @@ class PlayerIndex {
.add(filter, BooleanClause.Occur.FILTER) .add(filter, BooleanClause.Occur.FILTER)
.build() .build()
} }
2 -> { 2 -> {
if (activeMask.countOneBits() > 2) { if (activeMask.countOneBits() > 2) {
val filter = 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() BooleanQuery.Builder()
.add(fuzzy, BooleanClause.Occur.SHOULD) .add(fuzzy, BooleanClause.Occur.SHOULD)
.add(filter, BooleanClause.Occur.MUST_NOT) .add(filter, BooleanClause.Occur.MUST_NOT)
.build() .build()
} else fuzzy } else fuzzy
} }
3 -> fuzzy 3 -> fuzzy
else -> throw Error("wrong origins mask") else -> throw Error("wrong origins mask")
}.let { }.let {
@@ -113,4 +130,5 @@ class PlayerIndex {
val docs = searcher.search(query, MAX_HITS) val docs = searcher.search(query, MAX_HITS)
return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList() 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"> <script id="result" type="text/template">
{{for #data}} {{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}} {{/for}}
</script> </script>
<script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script> <script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script>