0

une base de données Étant donné contient une liste de personnes, où ils vivent, et leur richesse/revenu/niveau d'impôt, j'ai donné mon ElasticSearch 5.6.2 cette mise en correspondance:Comment trier les agrégations où les clés ont des caractères internationaux?

mappings => { 
    person => { 
     properties => { 
      name => { 
       type => 'text', 
       fields => { 
        raw => { 
         type => 'keyword', 
        }, 
       }, 
      }, 

      county => { 
       type => 'text', 
       fields => { 
        raw => { 
         type => 'keyword', 
        }, 
       }, 
      }, 

      community_name => { 
       type => 'text', 
       fields => { 
        raw => { 
         type => 'keyword', 
        }, 
       }, 
      }, 

      wealth => { 
       type => 'long', 
      }, 

      income => { 
       type => 'long', 
      }, 

      tax => { 
       type => 'long', 
      }, 
     }, 
    }, 
}, 

Un comté peut avoir plusieurs communautés , et je veux faire une agrégation qui donne un aperçu de la richesse/revenu/taxe moyenne pour chacun des comtés et pour chaque communauté de chaque comté.

Cela semble fonctionner:

aggs => { 
    counties => { 
     terms => { 
      field => 'county.raw', 
      size => 100, 
      order => { _term => 'asc' }, 
     }, 

     aggs => { 
      communities => { 
       terms => { 
        field => 'community_name.raw', 
        size => 1_000, 
        order => { _term => 'asc' }, 
       }, 

       aggs => { 
        avg_wealth => { 
         avg => { 
          field => 'wealth', 
         }, 
        }, 

        avg_income => { 
         avg => { 
          field => 'income', 
         }, 
        }, 

        avg_tax => { 
         avg => { 
          field => 'tax', 
         }, 
        }, 
       }, 

      }, 

      avg_wealth => { 
       avg => { 
        field => 'wealth', 
       }, 
      }, 

      avg_income => { 
       avg => { 
        field => 'income', 
       }, 
      }, 

      avg_tax => { 
       avg => { 
        field => 'tax', 
       }, 
      }, 

     }, 

    }, 
}, 

Cependant, le « comté » et « nom_communauté » ne sont pas triés correctement parce que certains d'entre eux ont des caractères norvégiens en eux, ce qui signifie que les sortes ES « Ål » avant " Øvre Eiker ", ce qui est faux.

Comment puis-je obtenir un tri norvégien correct?

EDIT: J'ai essayé de changer le champ "COMMUNITY_NAME" utiliser "icu_collation_keyword" au lieu de "mot-clé":

community_name => { 
    type => 'text', 
    fields => { 
     raw => { 
      type  => 'icu_collation_keyword', 
      index => 'false', 
      language => 'nb', 
     }, 
    }, 
}, 

Mais il en résulte une sortie médiocre:

Akershus - 276855 - 229202 - 80131 
    ᦥ免⡠႐໠  - 314430 - 243684 - 87105 
    ↘卑◥猔᠈〇㠖 - 202339 - 225665 - 78186 
    ⚞乀⃠᷀  - 306985 - 237405 - 83186 
    ⦘卓敫တ倎瀤 - 218060 - 218407 - 75602 
    ⸳䄓†怜〨 - 271174 - 216843 - 75257 
+0

Vous devriez essayer le champ [Mot-clé de classement de l'ICU] (https://www.elastic.co/guide/en/elasticsearch/plugins/5.6/analysis-icu-collation-keyword-field.html) – Val

+0

Ne pas dire que c'est la bonne solution, mais avez-vous envisagé d'utiliser ce filtre pour tenter de simplifier le tri? https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-asciifolding-tokenfilter.html – Miek

Répondre

0

Si la Le champ sur lequel vous voulez faire l'agrégation (community_name dans votre exemple) n'a toujours qu'une seule valeur, alors je pense que vous pourriez essayer l'approche suivante, qui est une extension de l'endroit où vous êtes allé jusqu'à présent.

Fondamentalement, vous pouvez ajouter une autre sous-agrégation sur la valeur originale, non tronquée, et la récupérer du côté client pour l'affichage.

Je montrerai sur une cartographie simplifiée:

PUT /icu_index 
{ 
    "mappings": { 
     "my_type": { 
      "properties": { 
       "community": { 
        "type": "text", 
        "fields": { 
         "raw": { 
          "type": "keyword" 
         }, 
         "norwegian": { 
          "type": "icu_collation_keyword", 
          "index": false, 
          "language": "nb" 
         } 
        } 
       }, 
       "wealth": { 
        "type": "long" 
       } 
      } 
     } 
    } 
} 

Nous stockons le nom de communauté:

  1. inchangée community;
  2. comme keyword dans community.raw;
  3. sous la forme icu_collation_keyword dans community.norwegian.

Ensuite, nous avons deux documents (ndlr: community_name a un argument de chaîne, pas la liste des chaînes):

PUT /icu_index/my_type/2 
{ 
    "community": "Ål", 
    "wealth": 10000 
} 

PUT /icu_index/my_type/3 
{ 
    "community": "Øvre Eiker", 
    "wealth": 5000 
} 

Maintenant, nous pouvons faire l'agrégation:

POST /icu_index/my_type/_search 
{ 
    "size": 0, 
    "aggs": { 
     "communities": { 
     "terms": { 
      "field": "community.norwegian", 
      "order": { 
       "_term": "asc" 
      } 
     }, 
     "aggs": { 
      "avg_wealth": { 
       "avg": { 
        "field": "wealth" 
       } 
      }, 
      "community_original": { 
       "terms": { 
        "field": "community.raw" 
       } 
      } 
     } 
     } 
    } 
} 

Nous sommes toujours en triant par community.norwegian, mais nous ajoutons également la sous-agrégation sur community.raw. Voyons le résultat:

"aggregations": { 
     "communities": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "⸳䃔楦၃৉瓅ᘂก捡㜂\u0000\u0001", 
       "doc_count": 1, 
       "community_original": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "Øvre Eiker", 
         "doc_count": 1 
        } 
        ] 
       }, 
       "avg_wealth": { 
        "value": 5000 
       } 
      }, 
      { 
       "key": "⸳䄏怠怜〨\u0000\u0000", 
       "doc_count": 1, 
       "community_original": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "Ål", 
         "doc_count": 1 
        } 
        ] 
       }, 
       "avg_wealth": { 
        "value": 10000 
       } 
      } 
     ] 
     } 
    } 

Maintenant, les compartiments sont triés par classification ICU du nom de communauté. Le premier compartiment avec la clé "⸳䃔楦၃৉瓅ᘂก捡㜂\u0000\u0001" a sa valeur d'origine en community_original.buckets[0].key, ce qui correspond à "Øvre Eiker".NB: Ce hack ne fonctionnera bien sûr pas si community_name peut être une liste de valeurs.

NB: Ce hack ne fonctionnera bien sûr pas si community_name peut être une liste de valeurs.

Espérons que ce hack aide!

+0

Malheureusement, "community_name" contient plus de 400 valeurs différentes; ils sont en fait des noms de municipalités dans chaque comté en Norvège. – toreau

+0

@toreau Je veux dire 1 par document (quel genre de sens, n'est-ce pas? Une seule adresse ne peut contenir qu'un nom de ville, n'est-ce pas?) SVP dites-moi si je me trompe. –