J'ai un index des professions (identifiant + profession):
<field name="occ_id" type="int" indexed="true" stored="true" required="true" />
<field name="occ_tx_name" type="text_es" indexed="true" stored="true" multiValued="false" />
<!-- Spanish -->
<fieldType name="text_es" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_es.txt" format="snowball" />
<filter class="solr.SpanishLightStemFilterFactory"/>
</analyzer>
</fieldType>
Il s'agit d'une vraie requête, pour trois identifiants (1, 195 et 129):
curl -X GET "http://192.168.1.11:8983/solr/cyp_occupations/select?indent=on&q=occ_id:1+occ_id:195+occ_id:129&wt=json"
{
"responseHeader":{
"status":0,
"QTime":1,
"params":{
"q":"occ_id:1 occ_id:195 occ_id:129",
"indent":"on",
"wt":"json"}},
"response":{"numFound":3,"start":0,"docs":[
{
"occ_id":1,
"occ_tx_name":"Abogado",
"_version_":1565225103805906944},
{
"occ_id":129,
"occ_tx_name":"Informático",
"_version_":1565225103843655680},
{
"occ_id":195,
"occ_tx_name":"Osteópata",
"_version_":1565225103858335746}]
}}
Deux d'entre eux ont des caractères accentués et un non. Alors recherchons par occ_tx_name sans utiliser d'accents:
curl -X GET "http://192.168.1.11:8983/solr/cyp_occupations/select?indent=on&q=occ_tx_name:abogado&wt=json"
{
"responseHeader":{
"status":0,
"QTime":1,
"params":{
"q":"occ_tx_name:abogado",
"indent":"on",
"wt":"json"}},
"response":{"numFound":1,"start":0,"docs":[
{
"occ_id":1,
"occ_tx_name":"Abogado",
"_version_":1565225103805906944}]
}}
curl -X GET "http://192.168.1.11:8983/solr/cyp_occupations/select?indent=on&q=occ_tx_name:informatico&wt=json"
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"occ_tx_name:informatico",
"indent":"on",
"wt":"json"}},
"response":{"numFound”:1,”start":0,"docs":[
{
"occ_id":129,
"occ_tx_name":"Informático",
"_version_":1565225103843655680}]
}}
curl -X GET "http://192.168.1.11:8983/solr/cyp_occupations/select?indent=on&q=occ_tx_name:osteopata&wt=json"
{
"responseHeader":{
"status":0,
"QTime":0,
"params":{
"q":"occ_tx_name:osteopata",
"indent":"on",
"wt":"json"}},
"response":{"numFound":0,"start":0,"docs":[]
}}
Je suis très ennuyé par le fait que la dernière recherche «osteopata» échoue, alors que «informatico» réussit. Les données source de l'index sont une simple table MySQL:
-- -----------------------------------------------------
-- Table `mydb`.`occ_occupation`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`occ_occupation` (
`occ_id` INT UNSIGNED NOT NULL,
`occ_tx_name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`occ_id`)
ENGINE = InnoDB
Le classement de la table est "utf8mb4_general_ci". L'index est créé avec DataImportHandler. Voici la définition:
<dataConfig>
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.1.11:3306/mydb"
user=“mydb” password=“mydb” />
<document name="occupations">
<entity name="occupation" pk="occ_id"
query="SELECT occ.occ_id, occ.occ_tx_name FROM occ_occupation occ WHERE occ.sta_bo_deleted = false">
<field column="occ_id" name="occ_id" />
<field column="occ_tx_name" name="occ_tx_name" />
</entity>
</document>
</dataConfig>
J'ai besoin d'indices pour détecter le problème. Quelqu'un peut-il m'aider? Merci d'avance.
3 réponses
Ok, j'ai découvert le problème source. J'ai ouvert mon script de chargement SQL avec VI, en mode hexadécimal.
Il s'agit du contenu hexadécimal de «Agrónomo» dans une instruction INSERT: 41 67 72 6f cc 81 6e 6f 6d 6f.
6f cc 81!!!! This is "o COMBINING ACUTE ACCENT" UTF code!!!!
Alors c'est ça le problème ... Ça doit être "c3 b3" ... J'obtiens les littéraux copier / coller à partir d'une page web, donc les caractères source sur l'origine étaient le problème.
Merci à vous deux, car j'en ai appris davantage sur l'âme de SOLR.
Cordialement.
Je ne pense pas que mysql ou vos paramètres jvm aient quoi que ce soit à voir avec cela. Je soupçonne que l'un fonctionne et que l'autre ne fonctionne pas probablement à cause de SpanishLightStemFilterFactory.
La bonne façon d'obtenir une correspondance, quels que soient les signes diacritiques, consiste à utiliser les éléments suivants:
<charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
Mettez cela avant votre tokenizer dans les chaînes d'index et d'analyseur de requêtes, et tout signe diacritique doit être converti en version ascii. Cela le ferait toujours fonctionner.
Ajoutez simplement solr.ASCIIFoldingFilterFactory
à votre chaîne d'analyseurs de filtres ou mieux encore créez un nouveau fieldType:
<!-- Spanish -->
<fieldType name="text_es_ascii_folding" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ASCIIFoldingFilterFactory" />
<filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_es.txt" format="snowball" />
<filter class="solr.SpanishLightStemFilterFactory"/>
</analyzer>
</fieldType>
Ce filtre convertit les caractères Unicode alphabétiques, numériques et symboliques qui ne sont pas dans le bloc Unicode Latin de base (les 127 premiers caractères ASCII) en leurs équivalents ASCII, s'il en existe un.
Cela devrait vous permettre de faire correspondre la recherche même si le caractère accentué est manquant. L'inconvénient est que des mots comme «cañon» et «canon» sont désormais équivalents et tous deux touchent les mêmes documents IIRC.
De nouvelles questions
solr
Apache Solr est un serveur de recherche open source basé sur la bibliothèque de recherche Lucene Java.