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.

0
Ernesto Salgado 20 avril 2017 à 23:14

3 réponses

Meilleure réponse

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.

0
Ernesto Salgado 21 avril 2017 à 21:52

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.

0
Persimmonium 20 avril 2017 à 21:02

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.

1
freedev 20 avril 2017 à 22:43